Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.ext.jmol

File JalviewJmolBinding.java

 

Coverage histogram

../../../img/srcFileCovDistChart6.png
33% of files have more coverage

Code metrics

120
282
44
1
1,027
704
137
0.49
6.41
44
3.11

Classes

Class Line # Actions
JalviewJmolBinding 59 282 137
0.52914852.9%
 

Contributing tests

This file is covered by 21 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
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.
11    *
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.
16    *
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.
20    */
21    package jalview.ext.jmol;
22   
23    import java.awt.Container;
24    import java.awt.event.ComponentEvent;
25    import java.awt.event.ComponentListener;
26    import java.io.File;
27    import java.net.URL;
28    import java.util.ArrayList;
29    import java.util.List;
30    import java.util.Map;
31    import java.util.StringTokenizer;
32    import java.util.Vector;
33   
34    import org.jmol.adapter.smarter.SmarterJmolAdapter;
35    import org.jmol.api.JmolAppConsoleInterface;
36    import org.jmol.api.JmolSelectionListener;
37    import org.jmol.api.JmolStatusListener;
38    import org.jmol.api.JmolViewer;
39    import org.jmol.c.CBK;
40    import org.jmol.viewer.Viewer;
41   
42    import jalview.api.AlignmentViewPanel;
43    import jalview.api.FeatureRenderer;
44    import jalview.api.SequenceRenderer;
45    import jalview.bin.Cache;
46    import jalview.datamodel.PDBEntry;
47    import jalview.datamodel.SequenceI;
48    import jalview.gui.IProgressIndicator;
49    import jalview.gui.StructureViewer.ViewerType;
50    import jalview.io.DataSourceType;
51    import jalview.io.StructureFile;
52    import jalview.structure.AtomSpec;
53    import jalview.structure.StructureCommand;
54    import jalview.structure.StructureCommandI;
55    import jalview.structure.StructureSelectionManager;
56    import jalview.structures.models.AAStructureBindingModel;
57    import javajs.util.BS;
58   
 
59    public abstract class JalviewJmolBinding extends AAStructureBindingModel
60    implements JmolStatusListener, JmolSelectionListener,
61    ComponentListener
62    {
63    private String lastMessage;
64   
65    /*
66    * when true, try to search the associated datamodel for sequences that are
67    * associated with any unknown structures in the Jmol view.
68    */
69    private boolean associateNewStructs = false;
70   
71    private Vector<String> atomsPicked = new Vector<>();
72   
73    private String lastCommand;
74   
75    private boolean loadedInline;
76   
77    private StringBuffer resetLastRes = new StringBuffer();
78   
79    public Viewer jmolViewer;
80   
 
81  7 toggle public JalviewJmolBinding(StructureSelectionManager ssm,
82    PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
83    DataSourceType protocol)
84    {
85  7 super(ssm, pdbentry, sequenceIs, protocol);
86  7 setStructureCommands(new JmolCommands());
87    /*
88    * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
89    * "jalviewJmol", ap.av.applet .getDocumentBase(),
90    * ap.av.applet.getCodeBase(), "", this);
91    *
92    * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
93    */
94    }
95   
 
96  0 toggle public JalviewJmolBinding(StructureSelectionManager ssm,
97    SequenceI[][] seqs, Viewer theViewer)
98    {
99  0 super(ssm, seqs);
100   
101  0 jmolViewer = theViewer;
102  0 jmolViewer.setJmolStatusListener(this);
103  0 jmolViewer.addSelectionListener(this);
104  0 setStructureCommands(new JmolCommands());
105    }
106   
107    /**
108    * construct a title string for the viewer window based on the data jalview
109    * knows about
110    *
111    * @return
112    */
 
113  7 toggle public String getViewerTitle()
114    {
115  7 return getViewerTitle("Jmol", true);
116    }
117   
 
118  83 toggle private String jmolScript(String script)
119    {
120  83 Cache.log.debug(">>Jmol>> " + script);
121  83 String s = jmolViewer.evalStringQuiet(script); // scriptWait(script); BH
122  83 Cache.log.debug("<<Jmol<< " + s);
123   
124  83 return s;
125    }
126   
 
127  28 toggle @Override
128    public List<String> executeCommand(StructureCommandI command,
129    boolean getReply)
130    {
131  28 if (command == null)
132    {
133  0 return null;
134    }
135  28 String cmd = command.getCommand();
136  28 jmolHistory(false);
137  28 if (lastCommand == null || !lastCommand.equals(cmd))
138    {
139  24 jmolScript(cmd + "\n");
140    }
141  28 jmolHistory(true);
142  28 lastCommand = cmd;
143  28 return null;
144    }
145   
 
146  0 toggle public void createImage(String file, String type, int quality)
147    {
148  0 System.out.println("JMOL CREATE IMAGE");
149    }
150   
 
151  4 toggle @Override
152    public String createImage(String fileName, String type,
153    Object textOrBytes, int quality)
154    {
155  4 System.out.println("JMOL CREATE IMAGE");
156  4 return null;
157    }
158   
 
159  0 toggle @Override
160    public String eval(String strEval)
161    {
162    // System.out.println(strEval);
163    // "# 'eval' is implemented only for the applet.";
164  0 return null;
165    }
166   
167    // End StructureListener
168    // //////////////////////////
169   
 
170  0 toggle @Override
171    public float[][] functionXY(String functionName, int x, int y)
172    {
173  0 return null;
174    }
175   
 
176  0 toggle @Override
177    public float[][][] functionXYZ(String functionName, int nx, int ny,
178    int nz)
179    {
180    // TODO Auto-generated method stub
181  0 return null;
182    }
183   
184    /**
185    * map between index of model filename returned from getPdbFile and the first
186    * index of models from this file in the viewer. Note - this is not trimmed -
187    * use getPdbFile to get number of unique models.
188    */
189    private int _modelFileNameMap[];
190   
 
191  74 toggle @Override
192    public synchronized String[] getStructureFiles()
193    {
194  74 if (jmolViewer == null)
195    {
196  2 return new String[0];
197    }
198   
199  72 if (modelFileNames == null)
200    {
201  35 int modelCount = jmolViewer.ms.mc;
202  35 String filePath = null;
203  35 List<String> mset = new ArrayList<>();
204  71 for (int i = 0; i < modelCount; ++i)
205    {
206    /*
207    * defensive check for null as getModelFileName can return null
208    * even when model count ms.mc is > 0
209    */
210  36 filePath = jmolViewer.ms.getModelFileName(i);
211  36 if (filePath != null && !mset.contains(filePath))
212    {
213  7 mset.add(filePath);
214    }
215    }
216  35 if (!mset.isEmpty())
217    {
218  6 modelFileNames = mset.toArray(new String[mset.size()]);
219    }
220    }
221   
222  72 return modelFileNames;
223    }
224   
225    /**
226    * map from string to applet
227    */
 
228  0 toggle @Override
229    public Map<String, Object> getRegistryInfo()
230    {
231    // TODO Auto-generated method stub
232  0 return null;
233    }
234   
235    // ///////////////////////////////
236    // JmolStatusListener
237   
 
238  0 toggle public void handlePopupMenu(int x, int y)
239    {
240    // jmolpopup.show(x, y);
241    // jmolpopup.jpiShow(x, y);
242    }
243   
244    /**
245    * Highlight zero, one or more atoms on the structure
246    */
 
247  0 toggle @Override
248    public void highlightAtoms(List<AtomSpec> atoms)
249    {
250  0 if (atoms != null)
251    {
252  0 if (resetLastRes.length() > 0)
253    {
254  0 jmolScript(resetLastRes.toString());
255  0 resetLastRes.setLength(0);
256    }
257  0 for (AtomSpec atom : atoms)
258    {
259  0 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
260    atom.getChain(), atom.getPdbFile());
261    }
262    }
263    }
264   
265    // jmol/ssm only
 
266  0 toggle public void highlightAtom(int atomIndex, int pdbResNum, String chain,
267    String pdbfile)
268    {
269  0 String modelId = getModelIdForFile(pdbfile);
270  0 if (modelId.isEmpty())
271    {
272  0 return;
273    }
274   
275  0 jmolHistory(false);
276   
277  0 StringBuilder selection = new StringBuilder(32);
278  0 StringBuilder cmd = new StringBuilder(64);
279  0 selection.append("select ").append(String.valueOf(pdbResNum));
280  0 selection.append(":");
281  0 if (!chain.equals(" "))
282    {
283  0 selection.append(chain);
284    }
285  0 selection.append(" /").append(modelId);
286   
287  0 cmd.append(selection).append(";wireframe 100;").append(selection)
288    .append(" and not hetero;").append("spacefill 200;select none");
289   
290  0 resetLastRes.append(selection).append(";wireframe 0;").append(selection)
291    .append(" and not hetero; spacefill 0;");
292   
293  0 jmolScript(cmd.toString());
294  0 jmolHistory(true);
295    }
296   
297    private boolean debug = true;
298   
 
299  56 toggle private void jmolHistory(boolean enable)
300    {
301  56 jmolScript("History " + ((debug || enable) ? "on" : "off"));
302    }
303   
 
304  0 toggle public void loadInline(String string)
305    {
306  0 loadedInline = true;
307    // TODO: re JAL-623
308    // viewer.loadInline(strModel, isAppend);
309    // could do this:
310    // construct fake fullPathName and fileName so we can identify the file
311    // later.
312    // Then, construct pass a reader for the string to Jmol.
313    // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
314    // fileName, null, reader, false, null, null, 0);
315  0 jmolViewer.openStringInline(string);
316    }
317   
 
318  1 toggle protected void mouseOverStructure(int atomIndex, final String strInfo)
319    {
320  1 int pdbResNum;
321  1 int alocsep = strInfo.indexOf("^");
322  1 int mdlSep = strInfo.indexOf("/");
323  1 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
324   
325  1 if (chainSeparator == -1)
326    {
327  0 chainSeparator = strInfo.indexOf(".");
328  0 if (mdlSep > -1 && mdlSep < chainSeparator)
329    {
330  0 chainSeparator1 = chainSeparator;
331  0 chainSeparator = mdlSep;
332    }
333    }
334    // handle insertion codes
335  1 if (alocsep != -1)
336    {
337  0 pdbResNum = Integer.parseInt(
338    strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
339   
340    }
341    else
342    {
343  1 pdbResNum = Integer.parseInt(
344    strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
345    }
346  1 String chainId;
347   
348  1 if (strInfo.indexOf(":") > -1)
349    {
350  1 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
351    strInfo.indexOf("."));
352    }
353    else
354    {
355  0 chainId = " ";
356    }
357   
358  1 String pdbfilename = modelFileNames[0]; // default is first model
359  1 if (mdlSep > -1)
360    {
361  1 if (chainSeparator1 == -1)
362    {
363  1 chainSeparator1 = strInfo.indexOf(".", mdlSep);
364    }
365  1 String mdlId = (chainSeparator1 > -1)
366    ? strInfo.substring(mdlSep + 1, chainSeparator1)
367    : strInfo.substring(mdlSep + 1);
368  1 try
369    {
370    // recover PDB filename for the model hovered over.
371  1 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
372  1 if (_modelFileNameMap != null)
373    {
374  0 int _mp = _modelFileNameMap.length - 1;
375   
376  0 while (mnumber < _modelFileNameMap[_mp])
377    {
378  0 _mp--;
379    }
380  0 pdbfilename = modelFileNames[_mp];
381    }
382    else
383    {
384  1 if (mnumber >= 0 && mnumber < modelFileNames.length)
385    {
386  1 pdbfilename = modelFileNames[mnumber];
387    }
388   
389  1 if (pdbfilename == null)
390    {
391  0 pdbfilename = new File(jmolViewer.ms.getModelFileName(mnumber))
392    .getAbsolutePath();
393    }
394    }
395    } catch (Exception e)
396    {
397    }
398    }
399   
400    /*
401    * highlight position on alignment(s); if some text is returned,
402    * show this as a second line on the structure hover tooltip
403    */
404  1 String label = getSsm().mouseOverStructure(pdbResNum, chainId,
405    pdbfilename);
406  1 if (label != null)
407    {
408    // change comma to pipe separator (newline token for Jmol)
409  0 label = label.replace(',', '|');
410  0 StringTokenizer toks = new StringTokenizer(strInfo, " ");
411  0 StringBuilder sb = new StringBuilder();
412  0 sb.append("select ").append(String.valueOf(pdbResNum)).append(":")
413    .append(chainId).append("/1");
414  0 sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
415    .append(toks.nextToken());
416  0 sb.append("|").append(label).append("\"");
417  0 executeCommand(new StructureCommand(sb.toString()), false);
418    }
419    }
420   
 
421  0 toggle public void notifyAtomHovered(int atomIndex, String strInfo, String data)
422    {
423  0 if (strInfo.equals(lastMessage))
424    {
425  0 return;
426    }
427  0 lastMessage = strInfo;
428  0 if (data != null)
429    {
430  0 System.err.println("Ignoring additional hover info: " + data
431    + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
432    }
433  0 mouseOverStructure(atomIndex, strInfo);
434    }
435   
436    /*
437    * { if (history != null && strStatus != null &&
438    * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
439    * } }
440    */
441   
 
442  0 toggle public void notifyAtomPicked(int atomIndex, String strInfo,
443    String strData)
444    {
445    /**
446    * this implements the toggle label behaviour copied from the original
447    * structure viewer, mc_view
448    */
449  0 if (strData != null)
450    {
451  0 System.err.println("Ignoring additional pick data string " + strData);
452    }
453  0 int chainSeparator = strInfo.indexOf(":");
454  0 int p = 0;
455  0 if (chainSeparator == -1)
456    {
457  0 chainSeparator = strInfo.indexOf(".");
458    }
459   
460  0 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
461    chainSeparator);
462  0 String mdlString = "";
463  0 if ((p = strInfo.indexOf(":")) > -1)
464    {
465  0 picked += strInfo.substring(p, strInfo.indexOf("."));
466    }
467   
468  0 if ((p = strInfo.indexOf("/")) > -1)
469    {
470  0 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
471    }
472  0 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
473    + mdlString + "))";
474  0 jmolHistory(false);
475   
476  0 if (!atomsPicked.contains(picked))
477    {
478  0 jmolScript("select " + picked + ";label %n %r:%c");
479  0 atomsPicked.addElement(picked);
480    }
481    else
482    {
483  0 jmolViewer.evalString("select " + picked + ";label off");
484  0 atomsPicked.removeElement(picked);
485    }
486  0 jmolHistory(true);
487    // TODO: in application this happens
488    //
489    // if (scriptWindow != null)
490    // {
491    // scriptWindow.sendConsoleMessage(strInfo);
492    // scriptWindow.sendConsoleMessage("\n");
493    // }
494   
495    }
496   
 
497  45 toggle @Override
498    public void notifyCallback(CBK type, Object[] data)
499    {
500  45 try
501    {
502  45 switch (type)
503    {
504  16 case LOADSTRUCT:
505  16 notifyFileLoaded((String) data[1], (String) data[2],
506    (String) data[3], (String) data[4],
507    ((Integer) data[5]).intValue());
508   
509  16 break;
510  0 case PICK:
511  0 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
512    (String) data[0]);
513    // also highlight in alignment
514    // deliberate fall through
515  0 case HOVER:
516  0 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
517    (String) data[0]);
518  0 break;
519  4 case SCRIPT:
520  4 notifyScriptTermination((String) data[2],
521    ((Integer) data[3]).intValue());
522  4 break;
523  6 case ECHO:
524  6 sendConsoleEcho((String) data[1]);
525  6 break;
526  0 case MESSAGE:
527  0 sendConsoleMessage(
528  0 (data == null) ? ((String) null) : (String) data[1]);
529  0 break;
530  2 case ERROR:
531    // System.err.println("Ignoring error callback.");
532  2 break;
533  14 case SYNC:
534  0 case RESIZE:
535  14 refreshGUI();
536  14 break;
537  3 case MEASURE:
538   
539  0 case CLICK:
540  0 default:
541  3 System.err.println(
542    "Unhandled callback " + type + " " + data[1].toString());
543  3 break;
544    }
545    } catch (Exception e)
546    {
547  0 System.err.println("Squashed Jmol callback handler error:");
548  0 e.printStackTrace();
549    }
550    }
551   
 
552  62 toggle @Override
553    public boolean notifyEnabled(CBK callbackPick)
554    {
555  62 switch (callbackPick)
556    {
557  6 case ECHO:
558  16 case LOADSTRUCT:
559  3 case MEASURE:
560  0 case MESSAGE:
561  0 case PICK:
562  4 case SCRIPT:
563  0 case HOVER:
564  2 case ERROR:
565  31 return true;
566  31 default:
567  31 return false;
568    }
569    }
570   
571    // incremented every time a load notification is successfully handled -
572    // lightweight mechanism for other threads to detect when they can start
573    // referrring to new structures.
574    private long loadNotifiesHandled = 0;
575   
 
576  18 toggle public long getLoadNotifiesHandled()
577    {
578  18 return loadNotifiesHandled;
579    }
580   
 
581  16 toggle public void notifyFileLoaded(String fullPathName, String fileName2,
582    String modelName, String errorMsg, int modelParts)
583    {
584  16 if (errorMsg != null)
585    {
586  5 fileLoadingError = errorMsg;
587  5 refreshGUI();
588  5 return;
589    }
590    // TODO: deal sensibly with models loaded inLine:
591    // modelName will be null, as will fullPathName.
592   
593    // the rest of this routine ignores the arguments, and simply interrogates
594    // the Jmol view to find out what structures it contains, and adds them to
595    // the structure selection manager.
596  11 fileLoadingError = null;
597  11 String[] oldmodels = modelFileNames;
598  11 modelFileNames = null;
599  11 boolean notifyLoaded = false;
600  11 String[] modelfilenames = getStructureFiles();
601  11 if (modelfilenames == null)
602    {
603    // Jmol is still loading files!
604  5 return;
605    }
606    // first check if we've lost any structures
607  6 if (oldmodels != null && oldmodels.length > 0)
608    {
609  1 int oldm = 0;
610  2 for (int i = 0; i < oldmodels.length; i++)
611    {
612  1 for (int n = 0; n < modelfilenames.length; n++)
613    {
614  1 if (modelfilenames[n] == oldmodels[i])
615    {
616  1 oldmodels[i] = null;
617  1 break;
618    }
619    }
620  1 if (oldmodels[i] != null)
621    {
622  0 oldm++;
623    }
624    }
625  1 if (oldm > 0)
626    {
627  0 String[] oldmfn = new String[oldm];
628  0 oldm = 0;
629  0 for (int i = 0; i < oldmodels.length; i++)
630    {
631  0 if (oldmodels[i] != null)
632    {
633  0 oldmfn[oldm++] = oldmodels[i];
634    }
635    }
636    // deregister the Jmol instance for these structures - we'll add
637    // ourselves again at the end for the current structure set.
638  0 getSsm().removeStructureViewerListener(this, oldmfn);
639    }
640    }
641  6 refreshPdbEntries();
642  13 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
643    {
644  7 String fileName = modelfilenames[modelnum];
645  7 boolean foundEntry = false;
646  7 StructureFile pdb = null;
647  7 String pdbfile = null;
648    // model was probably loaded inline - so check the pdb file hashcode
649  7 if (loadedInline)
650    {
651    // calculate essential attributes for the pdb data imported inline.
652    // prolly need to resolve modelnumber properly - for now just use our
653    // 'best guess'
654  0 pdbfile = jmolViewer.getData(
655    "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
656    }
657    // search pdbentries and sequences to find correct pdbentry for this
658    // model
659  16 for (int pe = 0; pe < getPdbCount(); pe++)
660    {
661  9 boolean matches = false;
662  9 addSequence(pe, getSequence()[pe]);
663  9 if (fileName == null)
664    {
665  0 if (false)
666    // see JAL-623 - need method of matching pasted data up
667    {
668  0 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
669    pdbfile, DataSourceType.PASTE, getIProgressIndicator());
670  0 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
671  0 matches = true;
672  0 foundEntry = true;
673    }
674    }
675    else
676    {
677  9 File fl = new File(getPdbEntry(pe).getFile());
678  9 matches = fl.equals(new File(fileName));
679  9 if (matches)
680    {
681  7 foundEntry = true;
682    // TODO: Jmol can in principle retrieve from CLASSLOADER but
683    // this
684    // needs
685    // to be tested. See mantis bug
686    // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
687  7 DataSourceType protocol = DataSourceType.URL;
688  7 try
689    {
690  7 if (fl.exists())
691    {
692  7 protocol = DataSourceType.FILE;
693    }
694    } catch (Exception e)
695    {
696    } catch (Error e)
697    {
698    }
699    // Explicitly map to the filename used by Jmol ;
700  7 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
701    fileName, protocol, getIProgressIndicator());
702    // pdbentry[pe].getFile(), protocol);
703   
704    }
705    }
706  9 if (matches)
707    {
708  7 stashFoundChains(pdb, fileName);
709  7 notifyLoaded = true;
710    }
711    }
712   
713  7 if (!foundEntry && associateNewStructs)
714    {
715    // this is a foreign pdb file that jalview doesn't know about - add
716    // it to the dataset and try to find a home - either on a matching
717    // sequence or as a new sequence.
718  0 String pdbcontent = jmolViewer.getData("/" + (modelnum + 1) + ".1",
719    "PDB");
720    // parse pdb file into a chain, etc.
721    // locate best match for pdb in associated views and add mapping to
722    // ssm
723    // if properly registered then
724  0 notifyLoaded = true;
725   
726    }
727    }
728    // FILE LOADED OK
729    // so finally, update the jmol bits and pieces
730    // if (jmolpopup != null)
731    // {
732    // // potential for deadlock here:
733    // // jmolpopup.updateComputedMenus();
734    // }
735  6 if (!isLoadingFromArchive())
736    {
737  3 jmolScript(
738    "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
739    }
740    // register ourselves as a listener and notify the gui that it needs to
741    // update itself.
742  6 getSsm().addStructureViewerListener(this);
743  6 if (notifyLoaded)
744    {
745  6 FeatureRenderer fr = getFeatureRenderer(null);
746  6 if (fr != null)
747    {
748  0 fr.featuresAdded();
749    }
750  6 refreshGUI();
751  6 loadNotifiesHandled++;
752    }
753  6 setLoadingFromArchive(false);
754    }
755   
 
756  7 toggle protected IProgressIndicator getIProgressIndicator()
757    {
758  7 return null;
759    }
760   
 
761  0 toggle public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
762    {
763  0 notifyAtomPicked(iatom, strMeasure, null);
764    }
765   
766    public abstract void notifyScriptTermination(String strStatus,
767    int msWalltime);
768   
769    /**
770    * display a message echoed from the jmol viewer
771    *
772    * @param strEcho
773    */
774    public abstract void sendConsoleEcho(String strEcho); /*
775    * { showConsole(true);
776    *
777    * history.append("\n" +
778    * strEcho); }
779    */
780   
781    // /End JmolStatusListener
782    // /////////////////////////////
783   
784    /**
785    * @param strStatus
786    * status message - usually the response received after a script
787    * executed
788    */
789    public abstract void sendConsoleMessage(String strStatus);
790   
 
791  0 toggle @Override
792    public void setCallbackFunction(String callbackType,
793    String callbackFunction)
794    {
795  0 System.err.println("Ignoring set-callback request to associate "
796    + callbackType + " with function " + callbackFunction);
797   
798    }
799   
 
800  0 toggle public void showHelp()
801    {
802  0 showUrl("http://wiki.jmol.org"
803    // BH 2018 "http://jmol.sourceforge.net/docs/JmolUserGuide/"
804    , "jmolHelp");
805    }
806   
807    /**
808    * open the URL somehow
809    *
810    * @param target
811    */
812    public abstract void showUrl(String url, String target);
813   
814    /**
815    * called to show or hide the associated console window container.
816    *
817    * @param show
818    */
819    public abstract void showConsole(boolean show);
820   
 
821  79 toggle public static Viewer getJmolData(JmolParser jmolParser)
822    {
823  79 return (Viewer) JmolViewer.allocateViewer(null, null, null, null, null,
824    "-x -o -n", jmolParser);
825    }
826   
827    /**
828    *
829    *
830    *
831    * @param renderPanel
832    * @param jmolfileio
833    * - when true will initialise jmol's file IO system (should be false
834    * in applet context)
835    * @param htmlName
836    * @param documentBase
837    * @param codeBase
838    * @param commandOptions
839    */
 
840  0 toggle public void allocateViewer(Container renderPanel, boolean jmolfileio,
841    String htmlName, URL documentBase, URL codeBase,
842    String commandOptions)
843    {
844  0 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
845    codeBase, commandOptions, null, null);
846    }
847   
848    /**
849    *
850    * @param renderPanel
851    * @param jmolfileio
852    * - when true will initialise jmol's file IO system (should be false
853    * in applet context)
854    * @param htmlName
855    * @param documentBase
856    * @param codeBase
857    * @param commandOptions
858    * @param consolePanel
859    * - panel to contain Jmol console
860    * @param buttonsToShow
861    * - buttons to show on the console, in order
862    */
 
863  7 toggle public void allocateViewer(Container renderPanel, boolean jmolfileio,
864    String htmlName, URL documentBase, URL codeBase,
865    String commandOptions, final Container consolePanel,
866    String buttonsToShow)
867    {
868   
869  7 System.err.println("Allocating Jmol Viewer: " + commandOptions);
870   
871  7 if (commandOptions == null)
872    {
873  0 commandOptions = "";
874    }
875  7 jmolViewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
876  7 (jmolfileio ? new SmarterJmolAdapter() : null),
877    htmlName + ((Object) this).toString(), documentBase, codeBase,
878    commandOptions, this);
879   
880  7 jmolViewer.setJmolStatusListener(this); // extends JmolCallbackListener
881   
882  7 try
883    {
884  7 console = createJmolConsole(consolePanel, buttonsToShow);
885    } catch (Throwable e)
886    {
887  0 System.err.println("Could not create Jmol application console. "
888    + e.getMessage());
889  0 e.printStackTrace();
890    }
891  7 if (consolePanel != null)
892    {
893  7 consolePanel.addComponentListener(this);
894   
895    }
896   
897    }
898   
899    protected abstract JmolAppConsoleInterface createJmolConsole(
900    Container consolePanel, String buttonsToShow);
901   
902    // BH 2018 -- Jmol console is not working due to problems with styled
903    // documents.
904   
905    protected org.jmol.api.JmolAppConsoleInterface console = null;
906   
 
907  0 toggle @Override
908    public int[] resizeInnerPanel(String data)
909    {
910    // Jalview doesn't honour resize panel requests
911  0 return null;
912    }
913   
914    /**
915    *
916    */
 
917  7 toggle protected void closeConsole()
918    {
919  7 if (console != null)
920    {
921  7 try
922    {
923  7 console.setVisible(false);
924    } catch (Error e)
925    {
926    } catch (Exception x)
927    {
928    }
929  7 ;
930  7 console = null;
931    }
932    }
933   
934    /**
935    * ComponentListener method
936    */
 
937  0 toggle @Override
938    public void componentMoved(ComponentEvent e)
939    {
940    }
941   
942    /**
943    * ComponentListener method
944    */
 
945  0 toggle @Override
946    public void componentResized(ComponentEvent e)
947    {
948    }
949   
950    /**
951    * ComponentListener method
952    */
 
953  0 toggle @Override
954    public void componentShown(ComponentEvent e)
955    {
956  0 showConsole(true);
957    }
958   
959    /**
960    * ComponentListener method
961    */
 
962  0 toggle @Override
963    public void componentHidden(ComponentEvent e)
964    {
965  0 showConsole(false);
966    }
967   
 
968  14 toggle @Override
969    protected String getModelIdForFile(String pdbFile)
970    {
971  14 if (modelFileNames == null)
972    {
973  0 return "";
974    }
975  17 for (int i = 0; i < modelFileNames.length; i++)
976    {
977  17 if (modelFileNames[i].equalsIgnoreCase(pdbFile))
978    {
979  14 return String.valueOf(i + 1);
980    }
981    }
982  0 return "";
983    }
984   
 
985  2 toggle @Override
986    protected ViewerType getViewerType()
987    {
988  2 return ViewerType.JMOL;
989    }
990   
 
991  0 toggle @Override
992    protected String getModelId(int pdbfnum, String file)
993    {
994  0 return String.valueOf(pdbfnum + 1);
995    }
996   
997    /**
998    * Returns ".spt" - the Jmol session file extension
999    *
1000    * @return
1001    * @see https://chemapps.stolaf.edu/jmol/docs/#writemodel
1002    */
 
1003  2 toggle @Override
1004    public String getSessionFileExtension()
1005    {
1006  2 return ".spt";
1007    }
1008   
 
1009  0 toggle @Override
1010    public void selectionChanged(BS arg0)
1011    {
1012    // TODO Auto-generated method stub
1013   
1014    }
1015   
 
1016  0 toggle @Override
1017    public SequenceRenderer getSequenceRenderer(AlignmentViewPanel avp)
1018    {
1019  0 return new jalview.gui.SequenceRenderer(avp.getAlignViewport());
1020    }
1021   
 
1022  0 toggle @Override
1023    public String getHelpURL()
1024    {
1025  0 return "http://wiki.jmol.org"; // BH 2018
1026    }
1027    }