1 /* $RCSfile$ 2 * $Author: hansonr $ 3 * $Date: 2016-07-13 14:51:46 -0500 (Wed, 13 Jul 2016) $ 4 * $Revision: 19253 $ 5 * 6 * Copyright (C) 2002-2006 Miguel, Jmol Development, www.jmol.org 7 * 8 * Contact: jmol-developers@lists.sf.net 9 * 10 * This library is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU Lesser General Public 12 * License as published by the Free Software Foundation; either 13 * version 2.1 of the License, or (at your option) any later version. 14 * 15 * This library is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * Lesser General Public License for more details. 19 * 20 * You should have received a copy of the GNU Lesser General Public 21 * License along with this library; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23 */ 24 package org.jmol.viewer; 25 26 import java.io.BufferedInputStream; 27 import java.io.BufferedReader; 28 import java.io.IOException; 29 import java.io.Reader; 30 import java.net.URL; 31 import java.util.Arrays; 32 import java.util.Hashtable; 33 import java.util.Iterator; 34 import java.util.Map; 35 import java.util.Map.Entry; 36 import java.util.Properties; 37 38 import org.jmol.adapter.readers.quantum.NBOParser; 39 import org.jmol.adapter.smarter.SmarterJmolAdapter; 40 import org.jmol.api.AtomIndexIterator; 41 import org.jmol.api.GenericMenuInterface; 42 import org.jmol.api.GenericMouseInterface; 43 import org.jmol.api.GenericPlatform; 44 import org.jmol.api.Interface; 45 import org.jmol.api.JmolAdapter; 46 import org.jmol.api.JmolAnnotationParser; 47 import org.jmol.api.JmolAppConsoleInterface; 48 import org.jmol.api.JmolCallbackListener; 49 import org.jmol.api.JmolDataManager; 50 import org.jmol.api.JmolInChI; 51 import org.jmol.api.JmolJSpecView; 52 import org.jmol.api.JmolNMRInterface; 53 import org.jmol.api.JmolPropertyManager; 54 import org.jmol.api.JmolRendererInterface; 55 import org.jmol.api.JmolRepaintManager; 56 import org.jmol.api.JmolScriptEditorInterface; 57 import org.jmol.api.JmolScriptEvaluator; 58 import org.jmol.api.JmolScriptFunction; 59 import org.jmol.api.JmolScriptManager; 60 import org.jmol.api.JmolSelectionListener; 61 import org.jmol.api.JmolStatusListener; 62 import org.jmol.api.JmolViewer; 63 import org.jmol.api.PlatformViewer; 64 import org.jmol.api.SmilesMatcherInterface; 65 import org.jmol.api.SymmetryInterface; 66 import org.jmol.api.js.JSmolAppletObject; 67 import org.jmol.api.js.JmolToJSmolInterface; 68 import org.jmol.atomdata.AtomData; 69 import org.jmol.atomdata.AtomDataServer; 70 import org.jmol.atomdata.RadiusData; 71 import org.jmol.atomdata.RadiusData.EnumType; 72 import org.jmol.awtjs.Event; 73 import org.jmol.c.FIL; 74 import org.jmol.c.STER; 75 import org.jmol.c.STR; 76 import org.jmol.c.VDW; 77 import org.jmol.i18n.GT; 78 import org.jmol.minimize.Minimizer; 79 import org.jmol.modelkit.ModelKitPopup; 80 import org.jmol.modelset.Atom; 81 import org.jmol.modelset.AtomCollection; 82 import org.jmol.modelset.Bond; 83 import org.jmol.modelset.LabelToken; 84 import org.jmol.modelset.Measurement; 85 import org.jmol.modelset.MeasurementData; 86 import org.jmol.modelset.MeasurementPending; 87 import org.jmol.modelset.Model; 88 import org.jmol.modelset.ModelSet; 89 import org.jmol.modelset.Orientation; 90 import org.jmol.modelset.StateScript; 91 import org.jmol.modelsetbio.BioResolver; 92 import org.jmol.script.SV; 93 import org.jmol.script.ScriptContext; 94 import org.jmol.script.ScriptEval; 95 import org.jmol.script.T; 96 import org.jmol.thread.TimeoutThread; 97 import org.jmol.util.BSUtil; 98 import org.jmol.util.BoxInfo; 99 import org.jmol.util.C; 100 import org.jmol.util.CommandHistory; 101 import org.jmol.util.Elements; 102 import org.jmol.util.Escape; 103 import org.jmol.util.Font; 104 import org.jmol.util.GData; 105 import org.jmol.util.JmolMolecule; 106 import org.jmol.util.Logger; 107 import org.jmol.util.Node; 108 import org.jmol.util.Parser; 109 import org.jmol.util.Rectangle; 110 import org.jmol.util.TempArray; 111 import org.jmol.util.Triangulator; 112 import org.jmol.viewer.binding.Binding; 113 114 import javajs.J2SIgnoreImport; 115 import javajs.api.GenericCifDataParser; 116 import javajs.api.GenericZipTools; 117 import javajs.util.AU; 118 import javajs.util.BS; 119 import javajs.util.CU; 120 import javajs.util.DF; 121 import javajs.util.JSJSONParser; 122 import javajs.util.Lst; 123 import javajs.util.M3; 124 import javajs.util.M4; 125 import javajs.util.OC; 126 import javajs.util.P3; 127 import javajs.util.P3i; 128 import javajs.util.P4; 129 import javajs.util.PT; 130 import javajs.util.Quat; 131 import javajs.util.Rdr; 132 import javajs.util.SB; 133 import javajs.util.T3; 134 import javajs.util.V3; 135 136 /* 137 * 138 * **************************************************************** 139 * The JmolViewer can be used to render client molecules. Clients implement the 140 * JmolAdapter. JmolViewer uses this interface to extract information from the 141 * client data structures and render the molecule to the supplied 142 * java.awt.Component 143 * 144 * The JmolViewer runs on Java 1.5+ virtual machines. The 3d graphics rendering 145 * package is a software implementation of a z-buffer. It does not use Java3D 146 * and does not use Graphics2D from Java 1.2. 147 * 148 * public here is a test for applet-applet and JS-applet communication the idea 149 * being that applet.getProperty("jmolViewer") returns this Viewer object, 150 * allowing direct inter-process access to public methods. 151 * 152 * e.g. 153 * 154 * applet.getProperty("jmolApplet").getFullPathName() 155 * 156 * 157 * This vwr can also be used with JmolData.jar, which is a 158 * frameless version of Jmol that can be used to batch-process 159 * scripts from the command line. No shapes, no labels, no export 160 * to JPG -- just raw data checking and output. 161 * 162 * 163 * NOSCRIPTING option: 2/2013 164 * 165 * This option provides a smaller load footprint for JavaScript JSmol 166 * and disallows: 167 * 168 * scripting 169 * modelKitMode 170 * slabbing of read JVXL files 171 * calculate hydrogens 172 * 173 * 174 * **************************************************************** 175 */ 176 177 @J2SIgnoreImport({ Runtime.class }) 178 public class Viewer extends JmolViewer 179 implements AtomDataServer, PlatformViewer { 180 181 public final static boolean nullDeletedAtoms = false; // only Jmol 15.2+ for now until better tested 182 183 public boolean testAsync;// = true; // testing only 184 185 static { 186 /** 187 * allows customization of Viewer -- not implemented in JSmol. 188 * 189 * @j2sNative 190 * 191 * self.Jmol && Jmol.extend && Jmol.extend("vwr", 192 * org.jmol.viewer.Viewer.prototype); 193 * 194 */ 195 { 196 } 197 } 198 199 @Override finalize()200 protected void finalize() throws Throwable { 201 if (Logger.debugging) 202 Logger.debug("vwr finalize " + this); 203 super.finalize(); 204 } 205 206 // these are all private now so we are certain they are not 207 // being accesed by any other classes 208 209 public boolean autoExit = false; 210 public boolean haveDisplay = false; 211 212 static public boolean isJS, isSwingJS, isWebGL; 213 public boolean isJSNoAWT; 214 public boolean isSingleThreaded; 215 public boolean queueOnHold = false; 216 217 public String fullName = ""; 218 public static String appletDocumentBase = ""; 219 public static String appletCodeBase = ""; 220 public static String appletIdiomaBase; 221 222 public static String jsDocumentBase = ""; 223 224 public enum ACCESS { 225 NONE, READSPT, ALL 226 } 227 228 public Object compiler; 229 public Map<String, Object> definedAtomSets; 230 public ModelSet ms; 231 public FileManager fm; 232 233 public boolean isApplet, isJNLP; 234 235 public boolean isSyntaxAndFileCheck = false; 236 public boolean isSyntaxCheck = false; 237 public boolean listCommands = false; 238 boolean mustRender = false; 239 240 public String htmlName = ""; 241 public String appletName = ""; 242 243 public int tryPt; 244 245 private String insertedCommand = ""; 246 setInsertedCommand(String strScript)247 public void setInsertedCommand(String strScript) { 248 insertedCommand = strScript; 249 } 250 251 public GData gdata; 252 public JSmolAppletObject html5Applet; // j2s only 253 public static JmolToJSmolInterface jmolObject; 254 255 public ActionManager acm; 256 public AnimationManager am; 257 public ColorManager cm; 258 JmolDataManager dm; 259 public ShapeManager shm; 260 public SelectionManager slm; 261 JmolRepaintManager rm; 262 public GlobalSettings g; 263 public StatusManager sm; 264 public TransformManager tm; 265 266 public static String strJavaVendor = "Java: " 267 + System.getProperty("java.vendor", "j2s"); 268 public static String strOSName = System.getProperty("os.name", ""); 269 public static String strJavaVersion = "Java " 270 + System.getProperty("java.version", ""); 271 272 String syncId = ""; 273 String logFilePath = ""; 274 275 private boolean allowScripting; 276 public boolean isPrintOnly; 277 public boolean isSignedApplet = false; 278 private boolean isSignedAppletLocal = false; 279 private boolean isSilent; 280 private boolean multiTouch; 281 public boolean noGraphicsAllowed; 282 private boolean useCommandThread = false; 283 284 private String commandOptions; 285 public Map<String, Object> vwrOptions; 286 public Object display; 287 private JmolAdapter modelAdapter; 288 private ACCESS access; 289 private CommandHistory commandHistory; 290 291 public ModelManager mm; 292 public StateManager stm; 293 private JmolScriptManager scm; 294 public JmolScriptEvaluator eval; 295 private TempArray tempArray; 296 297 public boolean allowArrayDotNotation; 298 public boolean async; 299 public Object executor; 300 301 private static String version_date; 302 getJmolVersion()303 public static String getJmolVersion() { 304 return (version_date == null ? version_date = JC.version + " " + JC.date 305 : version_date); 306 } 307 308 /** 309 * old way... 310 * 311 * @param display 312 * @param modelAdapter 313 * @param fullName 314 * @param documentBase 315 * @param codeBase 316 * @param commandOptions 317 * @param statusListener 318 * @param implementedPlatform 319 * @return JmolViewer object 320 */ allocateViewer(Object display, JmolAdapter modelAdapter, String fullName, URL documentBase, URL codeBase, String commandOptions, JmolStatusListener statusListener, GenericPlatform implementedPlatform)321 protected static JmolViewer allocateViewer(Object display, 322 JmolAdapter modelAdapter, 323 String fullName, URL documentBase, 324 URL codeBase, 325 String commandOptions, 326 JmolStatusListener statusListener, 327 GenericPlatform implementedPlatform) { 328 329 Map<String, Object> info = new Hashtable<String, Object>(); 330 info.put("display", display); 331 info.put("adapter", modelAdapter); 332 info.put("statusListener", statusListener); 333 info.put("platform", implementedPlatform); 334 info.put("options", commandOptions); 335 info.put("fullName", fullName); 336 info.put("documentBase", documentBase); 337 info.put("codeBase", codeBase); 338 return new Viewer(info); 339 } 340 341 int screenWidth, screenHeight; 342 final Lst<String> actionStates; 343 final Lst<String> actionStatesRedo; 344 VDW defaultVdw; 345 346 public RadiusData rd; 347 public Map<Object, Object> chainMap; 348 private Lst<String> chainList; 349 private String errorMessage; 350 private String errorMessageUntranslated; 351 private double privateKey; 352 private boolean dataOnly; 353 354 /** 355 * new way... 356 * 357 * @param info 358 * "display" "adapter" "statusListener" "platform" "options" "fullName" 359 * "documentBase" "codeBase" "multiTouch" [options] "noGraphics" 360 * "printOnly" "previewOnly" "debug" "applet" "signedApplet" 361 * "appletProxy" "useCommandThread" "platform" [option] 362 * "backgroundTransparent" "exit" "listCommands" "check" "checkLoad" 363 * "silent" "access:READSPT" "access:NONE" "menuFile" 364 * "headlessMaxTimeMs" "headlessImage" "isDataOnly" "async" 365 **/ 366 Viewer(Map<String, Object> info)367 public Viewer(Map<String, Object> info) { 368 commandHistory = new CommandHistory(); 369 rd = new RadiusData(null, 0, null, null); 370 defaultVdw = VDW.JMOL; 371 localFunctions = new Hashtable<String, JmolScriptFunction>(); 372 privateKey = Math.random(); 373 actionStates = new Lst<String>(); 374 actionStatesRedo = new Lst<String>(); 375 chainMap = new Hashtable<Object, Object>(); 376 chainList = new Lst<String>(); 377 setOptions(info); 378 } 379 haveAccess(ACCESS a)380 public boolean haveAccess(ACCESS a) { 381 // disables WRITE, LOAD file:/, set logFile 382 // command line -g and -w options ARE available for final writing of image 383 return access == a; 384 } 385 386 @Override getModelAdapter()387 public JmolAdapter getModelAdapter() { 388 return (modelAdapter == null ? modelAdapter = new SmarterJmolAdapter() 389 : modelAdapter); 390 } 391 392 @Override getSmartsMatch(String smarts, BS bsSelected)393 public BS getSmartsMatch(String smarts, BS bsSelected) throws Exception { 394 if (bsSelected == null) 395 bsSelected = bsA(); 396 return getSmilesMatcher().getSubstructureSet(smarts, ms.at, ms.ac, 397 bsSelected, JC.SMILES_TYPE_SMARTS); 398 } 399 getSmartsMatchForNodes(String smarts, Node[] atoms)400 public BS getSmartsMatchForNodes(String smarts, Node[] atoms) 401 throws Exception { 402 return getSmilesMatcher().getSubstructureSet(smarts, atoms, atoms.length, 403 null, JC.SMILES_TYPE_SMARTS); 404 } 405 406 /** 407 * 408 * 409 * @param smilesOrSmarts 410 * @param bsSelected 411 * @param flags 412 * can be bitwise OR of JC.SMILES_* options, in particular, 413 * 414 * JC.SMILES_TYPE_SMARTS, JC.SMILES_TYPE_SMILES, and 415 * JC.SMILES_MAP_UNIQUE 416 * 417 * @return map 418 * @throws Exception 419 */ getSmartsMap(String smilesOrSmarts, BS bsSelected, int flags)420 public int[][] getSmartsMap(String smilesOrSmarts, BS bsSelected, int flags) 421 throws Exception { 422 if (bsSelected == null) 423 bsSelected = bsA(); 424 if (flags == 0) 425 flags = JC.SMILES_TYPE_SMARTS; 426 return getSmilesMatcher().getCorrelationMaps(smilesOrSmarts, ms.at, ms.ac, 427 bsSelected, flags); 428 } 429 430 @SuppressWarnings({ "unchecked", "null", "unused" }) setOptions(Map<String, Object> info)431 public void setOptions(Map<String, Object> info) { 432 // can be deferred 433 vwrOptions = info; 434 // could be a Component, or could be a JavaScript class 435 // use allocateViewer 436 if (Logger.debugging) { 437 Logger.debug("Viewer constructor " + this); 438 } 439 modelAdapter = (JmolAdapter) info.get("adapter"); 440 JmolStatusListener statusListener = (JmolStatusListener) info 441 .get("statusListener"); 442 fullName = (String) info.get("fullName"); 443 if (fullName == null) 444 fullName = ""; 445 Object o = info.get("codePath"); 446 if (o == null) 447 o = "../java/"; 448 appletCodeBase = o.toString(); 449 appletIdiomaBase = appletCodeBase.substring(0, 450 appletCodeBase.lastIndexOf("/", appletCodeBase.length() - 2) + 1) 451 + "idioma"; 452 o = info.get("documentBase"); 453 appletDocumentBase = (o == null ? "" : o.toString()); 454 o = info.get("options"); 455 commandOptions = (o == null ? "" : o.toString()); 456 457 if (info.containsKey("debug") || commandOptions.indexOf("-debug") >= 0) 458 Logger.setLogLevel(Logger.LEVEL_DEBUG); 459 if (isApplet && info.containsKey("maximumSize")) 460 setMaximumSize(((Integer) info.get("maximumSize")).intValue()); 461 462 isJNLP = checkOption2("isJNLP", "-jnlp"); 463 if (isJNLP) 464 Logger.info("setting JNLP mode TRUE"); 465 466 isSignedApplet = isJNLP || checkOption2("signedApplet", "-signed"); 467 isApplet = isSignedApplet || checkOption2("applet", "-applet"); 468 allowScripting = !checkOption2("noscripting", "-noscripting"); 469 int i = fullName.indexOf("__"); 470 htmlName = (i < 0 ? fullName : fullName.substring(0, i)); 471 appletName = PT.split(htmlName + "_", "_")[0]; 472 syncId = (i < 0 ? "" : fullName.substring(i + 2, fullName.length() - 2)); 473 access = (checkOption2("access:READSPT", "-r") ? ACCESS.READSPT 474 : checkOption2("access:NONE", "-R") ? ACCESS.NONE : ACCESS.ALL); 475 isPreviewOnly = info.containsKey("previewOnly"); 476 if (isPreviewOnly) 477 info.remove("previewOnly"); // see FilePreviewPanel 478 isPrintOnly = checkOption2("printOnly", "-p"); 479 dataOnly = checkOption2("isDataOnly", "\0"); 480 autoExit = checkOption2("exit", "-x"); 481 o = info.get("platform"); 482 String platform = "unknown"; 483 if (o == null) { 484 o = (commandOptions.contains("platform=") 485 ? commandOptions.substring(commandOptions.indexOf("platform=") + 9) 486 : "org.jmol.awt.Platform"); 487 // note that this must be the last option if give in commandOptions 488 } 489 if (o instanceof String) { 490 platform = (String) o; 491 isWebGL = (platform.indexOf(".awtjs.") >= 0); 492 isJS = isJSNoAWT = isWebGL || (platform.indexOf(".awtjs2d.") >= 0); 493 async = !dataOnly && !autoExit 494 && (testAsync || isJS && info.containsKey("async")); 495 JSmolAppletObject applet = null; 496 JmolToJSmolInterface jmol = null; 497 String javaver = "?"; 498 /** 499 * @j2sNative 500 * 501 * if(self.Jmol) { jmol = Jmol; applet = 502 * Jmol._applets[this.htmlName.split("_object")[0]]; javaver = 503 * Jmol._version; } 504 * 505 * 506 */ 507 { 508 javaver = null; 509 } 510 if (javaver != null) { 511 html5Applet = applet; 512 jmolObject = jmol; 513 strJavaVersion = javaver; 514 strJavaVendor = "Java2Script " + (isWebGL ? "(WebGL)" : "(HTML5)"); 515 } 516 o = Interface.getInterface(platform, this, "setOptions"); 517 } 518 apiPlatform = (GenericPlatform) o; 519 display = info.get("display"); 520 521 isSingleThreaded = apiPlatform.isSingleThreaded(); 522 noGraphicsAllowed = checkOption2("noDisplay", "-n"); 523 headless = apiPlatform.isHeadless(); 524 haveDisplay = (isWebGL 525 || display != null && !noGraphicsAllowed && !headless && !dataOnly); 526 noGraphicsAllowed &= (display == null); 527 headless |= noGraphicsAllowed; 528 if (haveDisplay) { 529 mustRender = true; 530 multiTouch = checkOption2("multiTouch", "-multitouch"); 531 /** 532 * @j2sNative 533 * 534 * if (!this.isWebGL) this.display = 535 * document.getElementById(this.display); 536 */ 537 { 538 } 539 } else { 540 display = null; 541 } 542 apiPlatform.setViewer(this, display); 543 o = info.get("graphicsAdapter"); 544 if (o == null && !isWebGL) 545 o = Interface.getOption("g3d.Graphics3D", this, "setOptions"); 546 gdata = (o == null && (isWebGL || !isJS) ? new GData() : (GData) o); 547 // intentionally throw an error here to restart the JavaScript async process 548 gdata.initialize(this, apiPlatform); 549 550 stm = new StateManager(this); 551 cm = new ColorManager(this, gdata); 552 sm = new StatusManager(this); 553 boolean is4D = info.containsKey("4DMouse"); 554 tm = TransformManager.getTransformManager(this, Integer.MAX_VALUE, 0, is4D); 555 slm = new SelectionManager(this); 556 if (haveDisplay) { 557 // must have language by now, as ActionManager uses GT._() 558 acm = (multiTouch 559 ? (ActionManager) Interface.getOption("multitouch.ActionManagerMT", 560 null, null) 561 : new ActionManager()); 562 acm.setViewer(this, 563 commandOptions + "-multitouch-" + info.get("multiTouch")); 564 mouse = apiPlatform.getMouseManager(privateKey, display); 565 if (multiTouch && !checkOption2("-simulated", "-simulated")) 566 apiPlatform.setTransparentCursor(display); 567 } 568 mm = new ModelManager(this); 569 shm = new ShapeManager(this); 570 tempArray = new TempArray(); 571 am = new AnimationManager(this); 572 o = info.get("repaintManager"); 573 if (o == null) 574 o = Interface.getOption("render.RepaintManager", this, "setOptions"); 575 if (isJS || o != null && !o.equals("")) 576 (rm = (JmolRepaintManager) o).set(this, shm); 577 // again we through a JS error if in async mode 578 ms = new ModelSet(this, null); 579 initialize(true, false); 580 fm = new FileManager(this); 581 582 definedAtomSets = new Hashtable<String, Object>(); 583 setJmolStatusListener(statusListener); 584 if (isApplet) { 585 Logger.info("vwrOptions: \n" + Escape.escapeMap(vwrOptions)); 586 // Java only, because Signed applet can't find correct path when local. 587 String path = (String) vwrOptions.get("documentLocation"); 588 if (!isJS && path != null && path.startsWith("file:/")) { 589 path = path.substring(0, 590 path.substring(0, (path + "?").indexOf("?")).lastIndexOf("/")); 591 Logger.info("setting current directory to " + path); 592 cd(path); 593 } 594 path = appletDocumentBase; 595 i = path.indexOf("#"); 596 if (i >= 0) 597 path = path.substring(0, i); 598 i = path.lastIndexOf("?"); 599 if (i >= 0) 600 path = path.substring(0, i); 601 i = path.lastIndexOf("/"); 602 if (i >= 0) 603 path = path.substring(0, i); 604 jsDocumentBase = path; 605 fm.setAppletContext(appletDocumentBase); 606 String appletProxy = (String) info.get("appletProxy"); 607 if (appletProxy != null) 608 setStringProperty("appletProxy", appletProxy); 609 if (isSignedApplet) { 610 logFilePath = PT.rep(appletCodeBase, "file://", ""); 611 logFilePath = PT.rep(logFilePath, "file:/", ""); 612 if (logFilePath.indexOf("//") >= 0) 613 logFilePath = null; 614 else 615 isSignedAppletLocal = true; 616 } else if (!isJS) { 617 logFilePath = null; 618 } 619 new GT(this, (String) info.get("language")); 620 // deferred here so that language is set 621 if (isJS) 622 acm.createActions(); 623 } else { 624 // not an applet -- used to pass along command line options 625 gdata.setBackgroundTransparent( 626 checkOption2("backgroundTransparent", "-b")); 627 isSilent = checkOption2("silent", "-i"); 628 if (isSilent) 629 Logger.setLogLevel(Logger.LEVEL_WARN); // no info, but warnings and 630 if (headless && !isSilent) 631 Logger.info("Operating headless display=" + display 632 + " nographicsallowed=" + noGraphicsAllowed); 633 // errors 634 isSyntaxAndFileCheck = checkOption2("checkLoad", "-C"); 635 isSyntaxCheck = isSyntaxAndFileCheck || checkOption2("check", "-c"); 636 listCommands = checkOption2("listCommands", "-l"); 637 cd("."); 638 if (headless) { 639 headlessImageParams = (Map<String, Object>) info.get("headlessImage"); 640 o = info.get("headlistMaxTimeMs"); 641 if (o == null) 642 o = Integer.valueOf(60000); 643 setTimeout("" + Math.random(), ((Integer) o).intValue(), "exitJmol"); 644 } 645 } 646 useCommandThread = !headless 647 && checkOption2("useCommandThread", "-threaded"); 648 setStartupBooleans(); 649 setIntProperty("_nProcessors", nProcessors); 650 /* 651 * Logger.info("jvm11orGreater=" + jvm11orGreater + "\njvm12orGreater=" + 652 * jvm12orGreater + "\njvm14orGreater=" + jvm14orGreater); 653 */ 654 if (!isSilent) { 655 Logger.info(JC.copyright + "\nJmol Version: " + getJmolVersion() 656 + "\njava.vendor: " + strJavaVendor + "\njava.version: " 657 + strJavaVersion + "\nos.name: " + strOSName + "\nAccess: " + access 658 + "\nmemory: " + getP("_memory") + "\nprocessors available: " 659 + nProcessors + "\nuseCommandThread: " + useCommandThread 660 + (!isApplet ? "" 661 : "\nappletId:" + htmlName 662 + (isSignedApplet ? " (signed)" : ""))); 663 } 664 zap(false, true, false); // here to allow echos 665 g.setO("language", GT.getLanguage()); 666 g.setO("_hoverLabel", hoverLabel); 667 stm.setJmolDefaults(); 668 // this code will be shared between Jmol 14.0 and 14.1 669 Elements.covalentVersion = Elements.RAD_COV_BODR_2014_02_22; 670 allowArrayDotNotation = true; 671 if (allowScripting) 672 getScriptManager(); 673 } 674 675 // //////////// screen/image methods /////////////// 676 677 // final Rectangle rectClip = new Rectangle(); 678 679 private int maximumSize = Integer.MAX_VALUE; 680 setMaximumSize(int x)681 private void setMaximumSize(int x) { 682 maximumSize = Math.max(x, 100); 683 } 684 685 /** 686 * A graphics from a "slave" stereo display that has been synchronized with 687 * this this applet. 688 */ 689 private Object gRight; 690 691 /** 692 * A flag to indicate that THIS is the right-side panel of a pair of synced 693 * applets running a left-right stereo display (that would be piped into a 694 * dual-image polarized projector system such as GeoWall). 695 * 696 */ 697 private boolean isStereoSlave; 698 setStereo(boolean isStereoSlave, Object gRight)699 public void setStereo(boolean isStereoSlave, Object gRight) { 700 this.isStereoSlave = isStereoSlave; 701 this.gRight = gRight; 702 } 703 704 public float imageFontScaling = 1; 705 getMenu(String type)706 public String getMenu(String type) { 707 getPopupMenu(); 708 if (type.equals("\0")) { 709 popupMenu(screenWidth - 120, 0, 'j'); 710 return "OK"; 711 } 712 return (jmolpopup == null ? "" 713 : jmolpopup.jpiGetMenuAsString( 714 "Jmol version " + getJmolVersion() + "|_GET_MENU|" + type)); 715 } 716 717 @Override resizeInnerPanel(int width, int height)718 public int[] resizeInnerPanel(int width, int height) { 719 if (!autoExit && haveDisplay) 720 return sm.resizeInnerPanel(width, height); 721 setScreenDimension(width, height); 722 return new int[] { screenWidth, screenHeight }; 723 } 724 725 @Override setScreenDimension(int width, int height)726 public void setScreenDimension(int width, int height) { 727 // There is a bug in Netscape 4.7*+MacOS 9 when comparing dimension objects 728 // so don't try dim1.equals(dim2) 729 height = Math.min(height, maximumSize); 730 width = Math.min(width, maximumSize); 731 if (tm.stereoDoubleFull) 732 width = (width + 1) / 2; 733 if (screenWidth == width && screenHeight == height) 734 return; 735 resizeImage(width, height, false, false, true); 736 } 737 resizeImage(int width, int height, boolean isImageWrite, boolean isExport, boolean isReset)738 void resizeImage(int width, int height, boolean isImageWrite, 739 boolean isExport, boolean isReset) { 740 if (!isImageWrite && creatingImage) 741 return; 742 boolean wasAntialiased = antialiased; 743 antialiased = (isReset 744 ? g.antialiasDisplay && checkMotionRendering(T.antialiasdisplay) 745 : isImageWrite && !isExport ? g.antialiasImages : false); 746 if (!isExport && !isImageWrite 747 && (width > 0 || wasAntialiased != antialiased)) 748 setShapeProperty(JC.SHAPE_LABELS, "clearBoxes", null); 749 imageFontScaling = (antialiased ? 2f : 1f) 750 * (isReset || tm.scale3D || width <= 0 ? 1 751 : (g.zoomLarge == (height > width) ? height : width) * 1f 752 / getScreenDim()); 753 if (width > 0) { 754 screenWidth = width; 755 screenHeight = height; 756 if (!isImageWrite) { 757 g.setI("_width", width); 758 g.setI("_height", height); 759 // setStatusResized(width, height); 760 } 761 } else { 762 width = (screenWidth == 0 ? screenWidth = 500 : screenWidth); 763 height = (screenHeight == 0 ? screenHeight = 500 : screenHeight); 764 } 765 tm.setScreenParameters(width, height, 766 isImageWrite || isReset ? g.zoomLarge : false, antialiased, false, 767 false); 768 gdata.setWindowParameters(width, height, antialiased); 769 if (width > 0 && !isImageWrite) 770 setStatusResized(width, height); 771 } 772 773 @Override getScreenWidth()774 public int getScreenWidth() { 775 return screenWidth; 776 } 777 778 @Override getScreenHeight()779 public int getScreenHeight() { 780 return screenHeight; 781 } 782 getScreenDim()783 public int getScreenDim() { 784 return (g.zoomLarge == (screenHeight > screenWidth) ? screenHeight 785 : screenWidth); 786 } 787 setWidthHeightVar()788 public void setWidthHeightVar() { 789 g.setI("_width", screenWidth); 790 g.setI("_height", screenHeight); 791 } 792 getBoundBoxCenterX()793 public int getBoundBoxCenterX() { 794 // used by axes renderer 795 return screenWidth / 2; 796 } 797 getBoundBoxCenterY()798 public int getBoundBoxCenterY() { 799 return screenHeight / 2; 800 } 801 updateWindow(int width, int height)802 private boolean updateWindow(int width, int height) { 803 if (!refreshing || creatingImage) 804 return (refreshing ? false : !isJS); 805 if (isTainted || tm.slabEnabled) 806 setModelVisibility(); 807 isTainted = false; 808 if (rm != null) { 809 if (width != 0) 810 setScreenDimension(width, height); 811 } 812 return true; 813 } 814 815 /** 816 * 817 * @param isDouble 818 * @param isImageWrite 819 * @return a java.awt.Image in the case of standard Jmol; an int[] in the case 820 * of Jmol-Android a canvas in the case of JSmol 821 */ getImage(boolean isDouble, boolean isImageWrite)822 private Object getImage(boolean isDouble, boolean isImageWrite) { 823 Object image = null; 824 try { 825 beginRendering(isDouble, isImageWrite); 826 render(); 827 gdata.endRendering(); 828 image = gdata.getScreenImage(isImageWrite); 829 } catch (Error er) { 830 gdata.getScreenImage(isImageWrite); 831 handleError(er, false); 832 setErrorMessage("Error during rendering: " + er, null); 833 } catch (Exception e) { 834 System.out.println("render error" + e); 835 } 836 return image; 837 } 838 beginRendering(boolean isDouble, boolean isImageWrite)839 private void beginRendering(boolean isDouble, boolean isImageWrite) { 840 gdata.beginRendering(tm.getStereoRotationMatrix(isDouble), g.translucent, 841 isImageWrite, !checkMotionRendering(T.translucent)); 842 } 843 844 public boolean antialiased; 845 render()846 private void render() { 847 if (mm.modelSet == null || !mustRender || !refreshing && !creatingImage 848 || rm == null) 849 return; 850 boolean antialias2 = antialiased && g.antialiasTranslucent; 851 int[] navMinMax = shm.finalizeAtoms(tm.bsSelectedAtoms, true); 852 if (isWebGL) { 853 rm.renderExport(gdata, ms, jsParams); 854 notifyViewerRepaintDone(); 855 return; 856 } 857 rm.render(gdata, ms, true, navMinMax); 858 if (gdata.setPass2(antialias2)) { 859 tm.setAntialias(antialias2); 860 rm.render(gdata, ms, false, null); 861 tm.setAntialias(antialiased); 862 } 863 } 864 865 /** 866 * 867 * @param graphic 868 * In JavaScript/HTML5, a Canvas.Context2d 869 * @param img 870 * @param x 871 * @param y 872 * @param isDTI 873 * DTI format -- scrunch width by factor of two 874 */ drawImage(Object graphic, Object img, int x, int y, boolean isDTI)875 private void drawImage(Object graphic, Object img, int x, int y, 876 boolean isDTI) { 877 if (graphic != null && img != null) { 878 apiPlatform.drawImage(graphic, img, x, y, screenWidth, screenHeight, 879 isDTI); 880 } 881 gdata.releaseScreenImage(); 882 } 883 getScreenImage()884 public Object getScreenImage() { 885 return getScreenImageBuffer(null, true); 886 } 887 888 /** 889 * Image.getJpgImage, ImageCreator.clipImage, getImageBytes, 890 * Viewer.renderScreenImageStereo 891 */ 892 @Override getScreenImageBuffer(Object g, boolean isImageWrite)893 public Object getScreenImageBuffer(Object g, boolean isImageWrite) { 894 if (isWebGL) 895 return (isImageWrite 896 ? apiPlatform.allocateRgbImage(0, 0, null, 0, false, true) 897 : null); 898 boolean isDouble = tm.stereoDoubleFull || tm.stereoDoubleDTI; 899 boolean isBicolor = tm.stereoMode.isBiColor(); 900 boolean mergeImages = (g == null && isDouble); 901 Object imageBuffer; 902 if (isBicolor) { 903 beginRendering(true, isImageWrite); 904 render(); 905 gdata.endRendering(); 906 gdata.snapshotAnaglyphChannelBytes(); 907 beginRendering(false, isImageWrite); 908 render(); 909 gdata.endRendering(); 910 gdata.applyAnaglygh(tm.stereoMode, tm.stereoColors); 911 imageBuffer = gdata.getScreenImage(isImageWrite); 912 } else { 913 imageBuffer = getImage(isDouble, isImageWrite); 914 } 915 Object imageBuffer2 = null; 916 if (mergeImages) { 917 imageBuffer2 = apiPlatform.newBufferedImage(imageBuffer, 918 (tm.stereoDoubleDTI ? screenWidth : screenWidth << 1), screenHeight); 919 g = apiPlatform.getGraphics(imageBuffer2); 920 } 921 if (g != null) { 922 if (isDouble) { 923 if (tm.stereoMode == STER.DTI) { 924 drawImage(g, imageBuffer, screenWidth >> 1, 0, true); 925 imageBuffer = getImage(false, false); 926 drawImage(g, imageBuffer, 0, 0, true); 927 g = null; 928 } else { 929 drawImage(g, imageBuffer, screenWidth, 0, false); 930 imageBuffer = getImage(false, false); 931 } 932 } 933 if (g != null) 934 drawImage(g, imageBuffer, 0, 0, false); 935 } 936 return (mergeImages ? imageBuffer2 : imageBuffer); 937 } 938 evalStringWaitStatusQueued(String returnType, String strScript, String statusList, boolean isQuiet, boolean isQueued)939 public synchronized Object evalStringWaitStatusQueued(String returnType, 940 String strScript, 941 String statusList, 942 boolean isQuiet, 943 boolean isQueued) { 944 /** 945 * @j2sNative 946 * 947 * if (strScript.indexOf("JSCONSOLE") == 0) { 948 * this.html5Applet._showInfo(strScript.indexOf("CLOSE")<0); if 949 * (strScript.indexOf("CLEAR") >= 0) 950 * this.html5Applet._clearConsole(); return null; } 951 */ 952 { 953 } 954 return (getScriptManager() == null ? null 955 : scm.evalStringWaitStatusQueued(returnType, strScript, statusList, 956 isQuiet, isQueued)); 957 } 958 popupMenu(int x, int y, char type)959 void popupMenu(int x, int y, char type) { 960 if (!haveDisplay || !refreshing || isPreviewOnly || g.disablePopupMenu) 961 return; 962 switch (type) { 963 case 'j': 964 try { 965 getPopupMenu(); 966 // can throw error if not present; that's ok 967 jmolpopup.jpiShow(x, y); 968 } catch (Throwable e) { 969 // no Swing -- tough luck! 970 Logger.info(e.toString()); 971 g.disablePopupMenu = true; 972 } 973 break; 974 case 'a': 975 case 'b': 976 case 'm': 977 // atom, bond, or main -- ignored 978 if (getModelkit(true) == null) { // bh was false? 979 return; 980 } 981 modelkit.jpiShow(x, y); 982 break; 983 } 984 } 985 getModelkit(boolean andShow)986 public ModelKitPopup getModelkit(boolean andShow) { 987 if (modelkit == null) { 988 modelkit = (ModelKitPopup) apiPlatform.getMenuPopup(null, 'm'); 989 } else if (andShow) { 990 modelkit.jpiUpdateComputedMenus(); 991 } 992 return modelkit; 993 } 994 getPopupMenu()995 Object getPopupMenu() { 996 if (g.disablePopupMenu) 997 return null; 998 if (jmolpopup == null) { 999 jmolpopup = (allowScripting ? apiPlatform.getMenuPopup(menuStructure, 'j') 1000 : null); 1001 if (jmolpopup == null) { 1002 if (!async) 1003 g.disablePopupMenu = true; 1004 return null; 1005 } 1006 } 1007 1008 if (isJSNoAWT) 1009 checkMenuUpdate(); 1010 return jmolpopup.jpiGetMenuAsObject(); 1011 } 1012 1013 @Override setMenu(String fileOrText, boolean isFile)1014 public void setMenu(String fileOrText, boolean isFile) { 1015 if (isFile) 1016 Logger 1017 .info("Setting menu " + (fileOrText.length() == 0 ? "to Jmol defaults" 1018 : "from file " + fileOrText)); 1019 if (fileOrText.length() == 0) 1020 fileOrText = null; 1021 else if (isFile) 1022 fileOrText = getFileAsString3(fileOrText, false, null); 1023 getProperty("DATA_API", "setMenu", fileOrText); 1024 sm.setCallbackFunction("menu", fileOrText); 1025 } 1026 1027 // // JavaScript callback methods for the applet 1028 1029 /* 1030 * 1031 * animFrameCallback echoCallback (defaults to messageCallback) errorCallback 1032 * evalCallback hoverCallback loadStructCallback measureCallback (defaults to 1033 * messageCallback) messageCallback (no local version) minimizationCallback 1034 * pickCallback resizeCallback scriptCallback (defaults to messageCallback) 1035 * syncCallback 1036 */ 1037 1038 /* 1039 * aniframeCallback is called: 1040 * 1041 * -- each time a frame is changed -- whenever the animation state is changed 1042 * -- whenever the visible frame range is changed 1043 * 1044 * jmolSetCallback("animFrameCallback", "myAnimFrameCallback") function 1045 * myAnimFrameCallback(frameNo, fileNo, modelNo, firstNo, lastNo) {} 1046 * 1047 * frameNo == the current frame in fileNo == the current file number, starting 1048 * at 1 modelNo == the current model number in the current file, starting at 1 1049 * firstNo == flag1 * (the first frame of the set, in file * 1000000 + model 1050 * notation) lastNo == flag2 * (the last frame of the set, in file * 1000000 + 1051 * model notation) 1052 * 1053 * where flag1 = 1 if animationDirection > 1 or -1 otherwise where flag2 = 1 1054 * if currentDirection > 1 or -1 otherwise 1055 * 1056 * RepaintManager.setStatusFrameChanged RepaintManager.setAnimationOff 1057 * RepaintManager.setCurrentModelIndex RepaintManager.clearAnimation 1058 * RepaintManager.rewindAnimation RepaintManager.setAnimationLast 1059 * RepaintManager.setAnimationRelative RepaintManager.setFrameRangeVisible 1060 * Viewer.setCurrentModelIndex Eval.file Eval.frame Eval.load 1061 * Viewer.createImage (when creating movie frames with the WRITE FRAMES 1062 * command) Viewer.initializeModel 1063 */ 1064 1065 private int prevFrame = Integer.MIN_VALUE; 1066 private float prevMorphModel; 1067 1068 /** 1069 * @param isVib 1070 * @param doNotify 1071 * ignored; not implemented 1072 */ setStatusFrameChanged(boolean isVib, boolean doNotify)1073 void setStatusFrameChanged(boolean isVib, boolean doNotify) { 1074 if (isVib) { 1075 // force reset (reading vibrations) 1076 prevFrame = Integer.MIN_VALUE; 1077 } 1078 tm.setVibrationPeriod(Float.NaN); 1079 int firstIndex = am.firstFrameIndex; 1080 int lastIndex = am.lastFrameIndex; 1081 1082 boolean isMovie = am.isMovie; 1083 int modelIndex = am.cmi; 1084 if (firstIndex == lastIndex && !isMovie) 1085 modelIndex = firstIndex; 1086 int frameID = getModelFileNumber(modelIndex); 1087 int currentFrame = am.cmi; 1088 int fileNo = frameID; 1089 int modelNo = frameID % 1000000; 1090 int firstNo = (isMovie ? firstIndex : getModelFileNumber(firstIndex)); 1091 int lastNo = (isMovie ? lastIndex : getModelFileNumber(lastIndex)); 1092 1093 String strModelNo; 1094 if (isMovie) { 1095 strModelNo = "" + (currentFrame + 1); 1096 } else if (fileNo == 0) { 1097 strModelNo = getModelNumberDotted(firstIndex); 1098 if (firstIndex != lastIndex) 1099 strModelNo += " - " + getModelNumberDotted(lastIndex); 1100 if (firstNo / 1000000 == lastNo / 1000000) 1101 fileNo = firstNo; 1102 } else { 1103 strModelNo = getModelNumberDotted(modelIndex); 1104 } 1105 if (fileNo != 0) 1106 fileNo = (fileNo < 1000000 ? 1 : fileNo / 1000000); 1107 1108 if (!isMovie) { 1109 g.setI("_currentFileNumber", fileNo); 1110 g.setI("_currentModelNumberInFile", modelNo); 1111 } 1112 float currentMorphModel = am.currentMorphModel; 1113 g.setI("_currentFrame", currentFrame); 1114 g.setI("_morphCount", am.morphCount); 1115 g.setF("_currentMorphFrame", currentMorphModel); 1116 g.setI("_frameID", frameID); 1117 g.setI("_modelIndex", modelIndex); 1118 g.setO("_modelNumber", strModelNo); 1119 g.setO("_modelName", (modelIndex < 0 ? "" : getModelName(modelIndex))); 1120 String title = (modelIndex < 0 ? "" : ms.getModelTitle(modelIndex)); 1121 g.setO("_modelTitle", title == null ? "" : title); 1122 g.setO("_modelFile", 1123 (modelIndex < 0 ? "" : ms.getModelFileName(modelIndex))); 1124 g.setO("_modelType", 1125 (modelIndex < 0 ? "" : ms.getModelFileType(modelIndex))); 1126 1127 if (currentFrame == prevFrame && currentMorphModel == prevMorphModel) 1128 return; 1129 prevFrame = currentFrame; 1130 prevMorphModel = currentMorphModel; 1131 1132 String entryName = getModelName(currentFrame); 1133 if (isMovie) { 1134 entryName = "" + (entryName == "" ? currentFrame + 1 : am.caf + 1) + ": " 1135 + entryName; 1136 } else { 1137 String script = "" + getModelNumberDotted(currentFrame); 1138 if (!entryName.equals(script)) 1139 entryName = script + ": " + entryName; 1140 } 1141 // there was a point where I thought frameNo and currentFrame 1142 // might be different. 1143 sm.setStatusFrameChanged(fileNo, modelNo, 1144 (am.animationDirection < 0 ? -firstNo : firstNo), 1145 (am.currentDirection < 0 ? -lastNo : lastNo), currentFrame, 1146 currentMorphModel, entryName); 1147 if (doHaveJDX()) 1148 getJSV().setModel(modelIndex); 1149 if (isJS) 1150 updateJSView(modelIndex, -1); 1151 } 1152 1153 // interaction with JSpecView 1154 1155 private boolean haveJDX; 1156 private JmolJSpecView jsv; 1157 doHaveJDX()1158 private boolean doHaveJDX() { 1159 // once-on, never off 1160 return (haveJDX 1161 || (haveJDX = getBooleanProperty("_JSpecView".toLowerCase()))); 1162 } 1163 getJSV()1164 JmolJSpecView getJSV() { 1165 if (jsv == null) { 1166 jsv = (JmolJSpecView) Interface.getOption("jsv.JSpecView", this, 1167 "script"); 1168 jsv.setViewer(this); 1169 } 1170 return jsv; 1171 } 1172 1173 /** 1174 * get the model designated as "baseModel" in a JCamp-MOL file for example, 1175 * the model used for bonding for an XYZVIB file or the model used as the base 1176 * model for a mass spec file. This might then allow pointing off a peak in 1177 * JSpecView to switch to the model that is involved in HNMR or CNMR 1178 * 1179 * @param modelIndex 1180 * 1181 * @return modelIndex 1182 */ 1183 getJDXBaseModelIndex(int modelIndex)1184 public int getJDXBaseModelIndex(int modelIndex) { 1185 if (!doHaveJDX()) 1186 return modelIndex; 1187 return getJSV().getBaseModelIndex(modelIndex); 1188 } 1189 getJspecViewProperties(Object myParam)1190 public Object getJspecViewProperties(Object myParam) { 1191 // from getProperty("JSpecView...") 1192 Object o = sm.getJspecViewProperties("" + myParam); 1193 if (o != null) 1194 haveJDX = true; 1195 return o; 1196 } 1197 1198 /* 1199 * echoCallback is one of the two main status reporting mechanisms. Along with 1200 * scriptCallback, it outputs to the console. Unlike scriptCallback, it does 1201 * not output to the status bar of the application or applet. If 1202 * messageCallback is enabled but not echoCallback, these messages go to the 1203 * messageCallback function instead. 1204 * 1205 * jmolSetCallback("echoCallback", "myEchoCallback") function 1206 * myEchoCallback(app, message, queueState) {} 1207 * 1208 * queueState = 1 -- queued queueState = 0 -- not queued 1209 * 1210 * serves: 1211 * 1212 * Eval.instructionDispatchLoop when app has -l flag 1213 * ForceField.steepestDescenTakeNSteps for minimization done 1214 * Viewer.setPropertyError Viewer.setBooleanProperty error 1215 * Viewer.setFloatProperty error Viewer.setIntProperty error 1216 * Viewer.setStringProperty error Viewer.showString adds a Logger.warn() 1217 * message Eval.showString calculate, cd, dataFrame, echo, error, getProperty, 1218 * history, isosurface, listIsosurface, pointGroup, print, set, show, write 1219 * ForceField.steepestDescentInitialize for initial energy 1220 * ForceField.steepestDescentTakeNSteps for minimization update 1221 * Viewer.showParameter 1222 */ 1223 scriptEcho(String strEcho)1224 public void scriptEcho(String strEcho) { 1225 if (!Logger.isActiveLevel(Logger.LEVEL_INFO)) 1226 return; 1227 if (isJS) 1228 System.out.println(strEcho); 1229 sm.setScriptEcho(strEcho, isScriptQueued()); 1230 if (listCommands && strEcho != null && strEcho.indexOf("$[") == 0) 1231 Logger.info(strEcho); 1232 } 1233 isScriptQueued()1234 private boolean isScriptQueued() { 1235 return scm != null && scm.isScriptQueued(); 1236 } 1237 1238 /* 1239 * errorCallback is a special callback that can be used to identify errors 1240 * during scripting and file i/o, and also indicate out of memory conditions 1241 * 1242 * jmolSetCallback("errorCallback", "myErrorCallback") function 1243 * myErrorCallback(app, errType, errMsg, objectInfo, errMsgUntranslated) {} 1244 * 1245 * errType == "Error" or "ScriptException" errMsg == error message, possibly 1246 * translated, with added information objectInfo == which object (such as an 1247 * isosurface) was involved errMsgUntranslated == just the basic message 1248 * 1249 * Viewer.notifyError Eval.runEval on Error and file loading Exceptions 1250 * Viewer.handleError Eval.runEval on OOM Error Viewer.createModelSet on OOM 1251 * model initialization Error Viewer.getImage on OOM rendering Error 1252 */ notifyError(String errType, String errMsg, String errMsgUntranslated)1253 public void notifyError(String errType, String errMsg, 1254 String errMsgUntranslated) { 1255 g.setO("_errormessage", errMsgUntranslated); 1256 sm.notifyError(errType, errMsg, errMsgUntranslated); 1257 } 1258 1259 /* 1260 * evalCallback is a special callback that evaluates expressions in JavaScript 1261 * rather than in Jmol. 1262 * 1263 * Viewer.jsEval Eval.loadScriptFileInternal Eval.Rpn.evaluateScript 1264 * Eval.script 1265 */ 1266 jsEval(String strEval)1267 public String jsEval(String strEval) { 1268 return "" + sm.jsEval(strEval); 1269 } 1270 jsEvalSV(String strEval)1271 public SV jsEvalSV(String strEval) { 1272 return SV.getVariable(isJS ? sm.jsEval(strEval) : jsEval(strEval)); 1273 } 1274 1275 /* 1276 * loadStructCallback indicates file load status. 1277 * 1278 * jmolSetCallback("loadStructCallback", "myLoadStructCallback") function 1279 * myLoadStructCallback(fullPathName, fileName, modelName, errorMsg, ptLoad) 1280 * {} 1281 * 1282 * ptLoad == JmolConstants.FILE_STATUS_NOT_LOADED == -1 ptLoad == JmolConstants.FILE_STATUS_ZAPPED == 0 1283 * ptLoad == JmolConstants.FILE_STATUS_CREATING_MODELSET == 2 ptLoad == 1284 * JmolConstants.FILE_STATUS_MODELSET_CREATED == 3 ptLoad == JmolConstants.FILE_STATUS_MODELS_DELETED == 5 1285 * 1286 * Only -1 (error loading), 0 (zapped), and 3 (model set created) messages are 1287 * passed on to the callback function. The others can be detected using 1288 * 1289 * set loadStructCallback "jmolscript:someFunctionName" 1290 * 1291 * At the time of calling of that method, the jmolVariable _loadPoint gives 1292 * the value of ptLoad. These load points are also recorded in the status 1293 * queue under types "fileLoaded" and "fileLoadError". 1294 * 1295 * Viewer.setFileLoadStatus Viewer.createModelSet (2, 3) 1296 * Viewer.createModelSetAndReturnError (-1, 1, 4) Viewer.deleteAtoms (5) 1297 * Viewer.zap (0) 1298 */ setFileLoadStatus(FIL ptLoad, String fullPathName, String fileName, String modelName, String strError, Boolean isAsync)1299 private void setFileLoadStatus(FIL ptLoad, String fullPathName, 1300 String fileName, String modelName, 1301 String strError, Boolean isAsync) { 1302 setErrorMessage(strError, null); 1303 g.setI("_loadPoint", ptLoad.getCode()); 1304 boolean doCallback = (ptLoad != FIL.CREATING_MODELSET); 1305 if (doCallback) 1306 setStatusFrameChanged(false, false); 1307 sm.setFileLoadStatus(fullPathName, fileName, modelName, strError, 1308 ptLoad.getCode(), doCallback, isAsync); 1309 if (doCallback) { 1310 // setStatusFrameChanged(false, true); // ensures proper title in JmolFrame but then we miss the file name 1311 if (doHaveJDX()) 1312 getJSV().setModel(am.cmi); 1313 if (isJS) 1314 updateJSView(am.cmi, -2); 1315 } 1316 1317 } 1318 getZapName()1319 public String getZapName() { 1320 return (g.modelKitMode ? JC.MODELKIT_ZAP_TITLE : JC.ZAP_TITLE); 1321 } 1322 1323 /* 1324 * measureCallback reports completed or pending measurements. Pending 1325 * measurements are measurements that the user has started but has not 1326 * completed -- this call comes when the user hesitates with the mouse over an 1327 * atom and the "rubber band" is showing 1328 * 1329 * jmolSetCallback("measureCallback", "myMeasureCallback") function 1330 * myMeasureCallback(strMeasure, intInfo, status) {} 1331 * 1332 * intInfo == (see below) status == "measurePicked" (intInfo == the number of 1333 * atoms in the measurement) "measureComplete" (intInfo == the current number 1334 * measurements) "measureDeleted" (intInfo == the index of the measurement 1335 * deleted or -1 for all) "measurePending" (intInfo == number of atoms picked 1336 * so far) 1337 * 1338 * strMeasure: 1339 * 1340 * For "set picking MEASURE ..." each time the user clicks an atom, a message 1341 * is sent to the pickCallback function (see below), and if the picking is set 1342 * to measure distance, angle, or torsion, then after the requisite number of 1343 * atoms is picked and the pick callback message is sent, a call is also made 1344 * to measureCallback with a string that indicates the measurement, such as: 1345 * 1346 * Angle O #9 - Si #7 - O #2 : 110.51877 1347 * 1348 * Under default conditions, when picking is not set to MEASURE, then 1349 * measurement reports are sent when the measure is completed, deleted, or 1350 * pending. These reports are in a psuedo array form that can be parsed more 1351 * easily, involving the atoms and measurement with units, for example: 1352 * 1353 * [Si #3, O #8, Si #7, 60.1 <degrees mark>] 1354 * 1355 * Viewer.setStatusMeasuring Measures.clear Measures.define 1356 * Measures.deleteMeasurement Measures.pending actionManager.atomPicked 1357 */ 1358 setStatusMeasuring(String status, int intInfo, String strMeasure, float value)1359 public void setStatusMeasuring(String status, int intInfo, String strMeasure, 1360 float value) { 1361 1362 // status intInfo 1363 1364 // measureCompleted index 1365 // measurePicked atom count 1366 // measurePending atom count 1367 // measureDeleted -1 (all) or index 1368 // measureSequence -2 1369 sm.setStatusMeasuring(status, intInfo, strMeasure, value); 1370 } 1371 1372 /* 1373 * minimizationCallback reports the status of a currently running 1374 * minimization. 1375 * 1376 * jmolSetCallback("minimizationCallback", "myMinimizationCallback") function 1377 * myMinimizationCallback(app, minStatus, minSteps, minEnergy, minEnergyDiff) 1378 * {} 1379 * 1380 * minStatus is one of "starting", "calculate", "running", "failed", or "done" 1381 * 1382 * Viewer.notifyMinimizationStatus Minimizer.endMinimization 1383 * Minimizer.getEnergyonly Minimizer.startMinimization 1384 * Minimizer.stepMinimization 1385 */ 1386 notifyMinimizationStatus()1387 public void notifyMinimizationStatus() { 1388 Object step = getP("_minimizationStep"); 1389 String ff = (String) getP("_minimizationForceField"); 1390 sm.notifyMinimizationStatus((String) getP("_minimizationStatus"), 1391 step instanceof String ? Integer.valueOf(0) : (Integer) step, 1392 (Float) getP("_minimizationEnergy"), 1393 (step.toString().equals("0") ? Float.valueOf(0) 1394 : (Float) getP("_minimizationEnergyDiff")), 1395 ff); 1396 } 1397 1398 /* 1399 * pickCallback returns information about an atom, bond, or DRAW object that 1400 * has been picked by the user. 1401 * 1402 * jmolSetCallback("pickCallback", "myPickCallback") function 1403 * myPickCallback(strInfo, iAtom, map) {} 1404 * 1405 * iAtom == the index of the atom picked or -2 for a draw object or -3 for a 1406 * bond 1407 * 1408 * strInfo depends upon the type of object picked: 1409 * 1410 * atom (iAtom>=0): a string determinied by the PICKLABEL parameter, which if "" delivers 1411 * the atom identity along with its coordinates 1412 * 1413 * bond (iAtom==-3): ["bond", bondIdentityString (quoted), x, y, z] where the coordinates 1414 * are of the midpoint of the bond 1415 * 1416 * draw (iAtom==-2): ["draw", ID(quoted), pickedModel, pickedVertex, x, y, z, 1417 * title(quoted)] 1418 * 1419 * isosurface (iAtom==-4): ["isosurface", ID(quoted), pickedModel, pickedVertex, x, y, z, 1420 * title(quoted)] 1421 * 1422 * map: 1423 * 1424 * atom: null 1425 * 1426 * bond: {pt, index, modelIndex, modelNumberDotted, type, strInfo} 1427 * 1428 * Draw, isosurface: {pt, modelIndex, modelNumberDotted, id, vertex, type} 1429 * 1430 * Viewer.setStatusAtomPicked Draw.checkObjectClicked (set picking DRAW) 1431 * Sticks.checkObjectClicked (set bondPicking TRUE; set picking IDENTIFY) 1432 * actionManager.atomPicked (set atomPicking TRUE; set picking IDENTIFY) 1433 * actionManager.queueAtom (during measurements) 1434 */ 1435 setStatusAtomPicked(int atomIndex, String info, Map<String, Object> map, boolean andSelect)1436 public void setStatusAtomPicked(int atomIndex, String info, 1437 Map<String, Object> map, boolean andSelect) { 1438 if (andSelect) 1439 setSelectionSet(BSUtil.newAndSetBit(atomIndex)); 1440 if (info == null) { 1441 info = g.pickLabel; 1442 info = (info.length() == 0 1443 ? getAtomInfoXYZ(atomIndex, g.messageStyleChime) 1444 : ms.getAtomInfo(atomIndex, info, ptTemp)); 1445 } 1446 setPicked(atomIndex, false); 1447 if (atomIndex < 0) { 1448 Measurement m = getPendingMeasurement(); 1449 if (m != null) 1450 info = info.substring(0, info.length() - 1) + ",\"" + m.getString() 1451 + "\"]"; 1452 } 1453 g.setO("_pickinfo", info); 1454 sm.setStatusAtomPicked(atomIndex, info, map); 1455 if (atomIndex < 0) 1456 return; 1457 int syncMode = sm.getSyncMode(); 1458 if (syncMode == StatusManager.SYNC_DRIVER && doHaveJDX()) 1459 getJSV().atomPicked(atomIndex); 1460 if (isJS) 1461 updateJSView(ms.at[atomIndex].mi, atomIndex); 1462 } 1463 1464 @Override getProperty(String returnType, String infoType, Object paramInfo)1465 public Object getProperty(String returnType, String infoType, 1466 Object paramInfo) { 1467 // accepts a BitSet paramInfo 1468 // return types include "JSON", "String", "readable", and anything else 1469 // returns the Java object. 1470 // Jmol 11.7.45 also uses this method as a general API 1471 // for getting and returning script data from the console and editor 1472 1473 if (!"DATA_API".equals(returnType)) 1474 return getPropertyManager().getProperty(returnType, infoType, paramInfo); 1475 1476 switch (("scriptCheck........." // 0 1477 + "consoleText........." // 20 1478 + "scriptEditor........" // 40 1479 + "scriptEditorState..." // 60 1480 + "getAppConsole......." // 80 1481 + "getScriptEditor....." // 100 1482 + "setMenu............." // 120 1483 + "spaceGroupInfo......" // 140 1484 + "disablePopupMenu...." // 160 1485 + "defaultDirectory...." // 180 1486 + "getPopupMenu........" // 200 1487 + "shapeManager........" // 220 1488 + "getPreference......." // 240 1489 ).indexOf(infoType)) { 1490 1491 case 0: 1492 return scriptCheckRet((String) paramInfo, true); 1493 case 20: 1494 return (appConsole == null ? "" : appConsole.getText()); 1495 case 40: 1496 showEditor((String[]) paramInfo); 1497 return null; 1498 case 60: 1499 scriptEditorVisible = ((Boolean) paramInfo).booleanValue(); 1500 return null; 1501 case 80: 1502 if (isKiosk) { 1503 appConsole = null; 1504 } else if (paramInfo instanceof JmolAppConsoleInterface) { 1505 appConsole = (JmolAppConsoleInterface) paramInfo; 1506 } else if (paramInfo != null && !((Boolean) paramInfo).booleanValue()) { 1507 appConsole = null; 1508 } else if (appConsole == null && paramInfo != null 1509 && ((Boolean) paramInfo).booleanValue()) { 1510 if (isJS) { 1511 appConsole = (JmolAppConsoleInterface) Interface 1512 .getOption("consolejs.AppletConsole", this, "script"); 1513 } 1514 /** 1515 * @j2sNative 1516 * 1517 * 1518 */ 1519 { 1520 for (int i = 0; i < 4 && appConsole == null; i++) { 1521 appConsole = (isApplet 1522 ? (JmolAppConsoleInterface) Interface 1523 .getOption("console.AppletConsole", null, null) 1524 : (JmolAppConsoleInterface) Interface.getInterface( 1525 "org.openscience.jmol.app.jmolpanel.console.AppConsole", 1526 null, null)); 1527 if (appConsole == null) 1528 try { 1529 System.out.println("Viewer can't start appConsole"); 1530 Thread.currentThread().wait(100); 1531 } catch (InterruptedException e) { 1532 // 1533 } 1534 } 1535 } 1536 if (appConsole != null) 1537 appConsole.start(this); 1538 } 1539 scriptEditor = (isJS || appConsole == null ? null 1540 : appConsole.getScriptEditor()); 1541 return appConsole; 1542 case 100: 1543 if (appConsole == null && paramInfo != null 1544 && ((Boolean) paramInfo).booleanValue()) { 1545 getProperty("DATA_API", "getAppConsole", Boolean.TRUE); 1546 scriptEditor = (appConsole == null ? null 1547 : appConsole.getScriptEditor()); 1548 } 1549 return scriptEditor; 1550 case 120: 1551 if (jmolpopup != null) 1552 jmolpopup.jpiDispose(); 1553 jmolpopup = null; 1554 return menuStructure = (String) paramInfo; 1555 case 140: 1556 return getSymTemp().getSpaceGroupInfo(ms, null, -1, false, null); 1557 case 160: 1558 g.disablePopupMenu = true; // no false here, because it's a 1559 // one-time setting 1560 return null; 1561 case 180: 1562 return g.defaultDirectory; 1563 case 200: 1564 if (paramInfo instanceof String) 1565 return getMenu((String) paramInfo); 1566 return getPopupMenu(); 1567 case 220: 1568 return shm.getProperty(paramInfo); 1569 case 240: 1570 return sm.syncSend("getPreference", paramInfo, 1); 1571 } 1572 Logger.error("ERROR in getProperty DATA_API: " + infoType); 1573 return null; 1574 } 1575 notifyMouseClicked(int x, int y, int action, int mode)1576 public int notifyMouseClicked(int x, int y, int action, int mode) { 1577 // change y to 0 at bottom 1578 int modifiers = Binding.getButtonMods(action); 1579 int clickCount = Binding.getClickCount(action); 1580 g.setI("_mouseX", x); 1581 g.setI("_mouseY", screenHeight - y); 1582 g.setI("_mouseAction", action); 1583 g.setI("_mouseModifiers", modifiers); 1584 g.setI("_clickCount", clickCount); 1585 return sm.setStatusClicked(x, screenHeight - y, action, clickCount, mode); 1586 } 1587 1588 private OutputManager outputManager; 1589 getOutputManager()1590 private OutputManager getOutputManager() { 1591 if (outputManager != null) 1592 return outputManager; 1593 return (outputManager = (OutputManager) Interface.getInterface( 1594 "org.jmol.viewer.OutputManager" + (isJS ? "JS" : "Awt"), this, "file")) 1595 .setViewer(this, privateKey); 1596 } 1597 1598 private GenericZipTools jzt; 1599 getJzt()1600 public GenericZipTools getJzt() { 1601 return (jzt == null 1602 ? jzt = (GenericZipTools) Interface.getInterface("javajs.util.ZipTools", 1603 this, "zip") 1604 : jzt); 1605 } 1606 readFileAsMap(BufferedInputStream bis, Map<String, Object> map, String name)1607 public void readFileAsMap(BufferedInputStream bis, Map<String, Object> map, 1608 String name) { 1609 getJzt().readFileAsMap(bis, map, name); 1610 } 1611 getZipDirectoryAsString(String fileName)1612 public String getZipDirectoryAsString(String fileName) { 1613 Object t = fm.getBufferedInputStreamOrErrorMessageFromName(fileName, 1614 fileName, false, false, null, false, true); 1615 return getJzt().getZipDirectoryAsStringAndClose((BufferedInputStream) t); 1616 } 1617 1618 /** 1619 * @return byte[] image, or null and an error message 1620 */ 1621 @Override getImageAsBytes(String type, int width, int height, int quality, String[] errMsg)1622 public byte[] getImageAsBytes(String type, int width, int height, int quality, 1623 String[] errMsg) { 1624 return getOutputManager().getImageAsBytes(type, width, height, quality, 1625 errMsg); 1626 } 1627 1628 @Override releaseScreenImage()1629 public void releaseScreenImage() { 1630 gdata.releaseScreenImage(); 1631 } 1632 setDisplay(Object canvas)1633 public void setDisplay(Object canvas) { 1634 // used by JSmol/HTML5 when a canvas is resized 1635 display = canvas; 1636 apiPlatform.setViewer(this, canvas); 1637 } 1638 newMeasurementData(String id, Lst<Object> points)1639 public MeasurementData newMeasurementData(String id, Lst<Object> points) { 1640 return ((MeasurementData) Interface 1641 .getInterface("org.jmol.modelset.MeasurementData", this, "script")) 1642 .init(id, this, points); 1643 } 1644 getDataManager()1645 private JmolDataManager getDataManager() { 1646 return (dm == null 1647 ? (dm = ((JmolDataManager) Interface 1648 .getInterface("org.jmol.viewer.DataManager", this, "script")) 1649 .set(this)) 1650 : dm); 1651 } 1652 getScriptManager()1653 private JmolScriptManager getScriptManager() { 1654 if (allowScripting && scm == null) { 1655 scm = (JmolScriptManager) Interface 1656 .getInterface("org.jmol.script.ScriptManager", this, "setOptions"); 1657 if (isJS && scm == null) 1658 throw new NullPointerException(); 1659 if (scm == null) { 1660 allowScripting = false; 1661 return null; 1662 } 1663 eval = scm.setViewer(this); 1664 if (useCommandThread) 1665 scm.startCommandWatcher(true); 1666 } 1667 return scm; 1668 } 1669 checkOption2(String key1, String key2)1670 private boolean checkOption2(String key1, String key2) { 1671 return (vwrOptions.containsKey(key1) 1672 && !vwrOptions.get(key1).toString().equals("false") 1673 || commandOptions.indexOf(key2) >= 0); 1674 } 1675 1676 public boolean isPreviewOnly; 1677 1678 /** 1679 * determined by GraphicsEnvironment.isHeadless() from java 1680 * -Djava.awt.headless=true 1681 * 1682 * disables command threading 1683 * 1684 * disables DELAY, TIMEOUT, PAUSE, LOOP, GOTO, SPIN <rate>, ANIMATION ON 1685 * 1686 * turns SPIN <rate> <end> into just ROTATE <end> 1687 */ 1688 1689 public boolean headless; 1690 setStartupBooleans()1691 private void setStartupBooleans() { 1692 setBooleanProperty("_applet", isApplet); 1693 setBooleanProperty("_JSpecView".toLowerCase(), false); 1694 setBooleanProperty("_signedApplet", isSignedApplet); 1695 setBooleanProperty("_headless", headless); 1696 setStringProperty("_restrict", "\"" + access + "\""); 1697 setBooleanProperty("_useCommandThread", useCommandThread); 1698 } 1699 getExportDriverList()1700 public String getExportDriverList() { 1701 return (haveAccess(ACCESS.ALL) 1702 ? (String) g.getParameter("exportDrivers", true) 1703 : ""); 1704 } 1705 1706 /** 1707 * end of life for this viewer 1708 */ 1709 @Override dispose()1710 public void dispose() { 1711 gRight = null; 1712 if (mouse != null) { 1713 acm.dispose(); 1714 mouse.dispose(); 1715 mouse = null; 1716 } 1717 clearScriptQueue(); 1718 clearThreads(); 1719 haltScriptExecution(); 1720 if (scm != null) 1721 scm.clear(true); 1722 gdata.destroy(); 1723 if (jmolpopup != null) 1724 jmolpopup.jpiDispose(); 1725 if (modelkit != null) 1726 modelkit.jpiDispose(); 1727 try { 1728 if (appConsole != null) { 1729 appConsole.dispose(); 1730 appConsole = null; 1731 } 1732 if (scriptEditor != null) { 1733 scriptEditor.dispose(); 1734 scriptEditor = null; 1735 } 1736 } catch (Exception e) { 1737 // ignore -- Disposal was interrupted only in Eclipse 1738 } 1739 } 1740 reset(boolean includingSpin)1741 public void reset(boolean includingSpin) { 1742 // Eval.reset() 1743 // initializeModel 1744 ms.calcBoundBoxDimensions(null, 1); 1745 axesAreTainted = true; 1746 tm.homePosition(includingSpin); 1747 if (ms.setCrystallographicDefaults()) 1748 stm.setCrystallographicDefaults(); 1749 else 1750 setAxesMode(T.axeswindow); 1751 prevFrame = Integer.MIN_VALUE; 1752 if (!tm.spinOn) 1753 setSync(); 1754 } 1755 1756 @Override homePosition()1757 public void homePosition() { 1758 evalString("reset spin"); 1759 } 1760 1761 /* 1762 * final Hashtable imageCache = new Hashtable(); 1763 * 1764 * void flushCachedImages() { imageCache.clear(); 1765 * GData.flushCachedColors(); } 1766 */ 1767 1768 // /////////////////////////////////////////////////////////////// 1769 // delegated to StateManager 1770 // /////////////////////////////////////////////////////////////// 1771 initialize(boolean clearUserVariables, boolean isPyMOL)1772 public void initialize(boolean clearUserVariables, boolean isPyMOL) { 1773 g = new GlobalSettings(this, g, clearUserVariables); 1774 setStartupBooleans(); 1775 setWidthHeightVar(); 1776 if (haveDisplay) { 1777 g.setB("_is2D", isJS && !isWebGL); 1778 g.setB("_multiTouchClient", acm.isMTClient()); 1779 g.setB("_multiTouchServer", acm.isMTServer()); 1780 } 1781 cm.setDefaultColors(false); 1782 setObjectColor("background", "black"); 1783 setObjectColor("axis1", "red"); 1784 setObjectColor("axis2", "green"); 1785 setObjectColor("axis3", "blue"); 1786 1787 // transfer default global settings to managers and g3d 1788 1789 am.setAnimationOn(false); 1790 am.setAnimationFps(g.animationFps); 1791 sm.playAudio(null); 1792 sm.allowStatusReporting = g.statusReporting; 1793 setBooleanProperty("antialiasDisplay", 1794 (isPyMOL ? true : g.antialiasDisplay)); 1795 stm.resetLighting(); 1796 tm.setDefaultPerspective(); 1797 } 1798 saveModelOrientation()1799 void saveModelOrientation() { 1800 ms.saveModelOrientation(am.cmi, stm.getOrientation()); 1801 } 1802 restoreModelOrientation(int modelIndex)1803 void restoreModelOrientation(int modelIndex) { 1804 Orientation o = ms.getModelOrientation(modelIndex); 1805 if (o != null) 1806 o.restore(-1, true); 1807 } 1808 restoreModelRotation(int modelIndex)1809 void restoreModelRotation(int modelIndex) { 1810 Orientation o = ms.getModelOrientation(modelIndex); 1811 if (o != null) 1812 o.restore(-1, false); 1813 } 1814 1815 // /////////////////////////////////////////////////////////////// 1816 // delegated to TransformManager 1817 // /////////////////////////////////////////////////////////////// 1818 1819 /** 1820 * This method is only called by JmolGLmol applet._refresh(); 1821 * 1822 * @return enough data to update a WebGL view 1823 * 1824 */ 1825 @SuppressWarnings("unused") getGLmolView()1826 public Object getGLmolView() { 1827 TransformManager tm = this.tm; 1828 T3 center = tm.fixedRotationCenter; 1829 Quat q = tm.getRotationQ(); 1830 float xtrans = tm.xTranslationFraction; 1831 float ytrans = tm.yTranslationFraction; 1832 float scale = tm.scalePixelsPerAngstrom; 1833 float zoom = tm.zmPctSet; 1834 float cd = tm.cameraDistance; 1835 float pc = tm.screenPixelCount; 1836 boolean pd = tm.perspectiveDepth; 1837 int width = tm.width; 1838 int height = tm.height; 1839 1840 /** 1841 * @j2sNative 1842 * 1843 * return { center:center, quaternion:q, xtrans:xtrans, 1844 * ytrans:ytrans, scale:scale, zoom:zoom, cameraDistance:cd, 1845 * pixelCount:pc, perspective:pd, width:width, height:height }; 1846 */ 1847 { 1848 return null; 1849 } 1850 } 1851 setRotationRadius(float angstroms, boolean doAll)1852 public void setRotationRadius(float angstroms, boolean doAll) { 1853 if (doAll) 1854 angstroms = tm.setRotationRadius(angstroms, false); 1855 // only set the rotationRadius if this is NOT a dataframe 1856 if (ms.setRotationRadius(am.cmi, angstroms)) 1857 g.setF("rotationRadius", angstroms); 1858 } 1859 setCenterBitSet(BS bsCenter, boolean doScale)1860 public void setCenterBitSet(BS bsCenter, boolean doScale) { 1861 // Eval 1862 // setCenterSelected 1863 if (isJmolDataFrame()) 1864 return; 1865 tm.setNewRotationCenter( 1866 (BSUtil.cardinalityOf(bsCenter) > 0 ? ms.getAtomSetCenter(bsCenter) 1867 : null), 1868 doScale); 1869 } 1870 setNewRotationCenter(P3 center)1871 public void setNewRotationCenter(P3 center) { 1872 // eval CENTER command 1873 if (!isJmolDataFrame()) 1874 tm.setNewRotationCenter(center, true); 1875 } 1876 navigate(int keyWhere, int modifiers)1877 void navigate(int keyWhere, int modifiers) { 1878 if (isJmolDataFrame()) 1879 return; 1880 tm.navigateKey(keyWhere, modifiers); 1881 if (!tm.vibrationOn && keyWhere != 0) 1882 refresh(REFRESH_REPAINT, "Viewer:navigate()"); 1883 } 1884 move(JmolScriptEvaluator eval, V3 dRot, float dZoom, V3 dTrans, float dSlab, float floatSecondsTotal, int fps)1885 public void move(JmolScriptEvaluator eval, V3 dRot, float dZoom, V3 dTrans, 1886 float dSlab, float floatSecondsTotal, int fps) { 1887 // from Eval 1888 tm.move(eval, dRot, dZoom, dTrans, dSlab, floatSecondsTotal, fps); 1889 moveUpdate(floatSecondsTotal); 1890 } 1891 moveTo(JmolScriptEvaluator eval, float floatSecondsTotal, P3 center, V3 rotAxis, float degrees, M3 rotationMatrix, float zoom, float xTrans, float yTrans, float rotationRadius, P3 navCenter, float xNav, float yNav, float navDepth, float cameraDepth, float cameraX, float cameraY)1892 public void moveTo(JmolScriptEvaluator eval, float floatSecondsTotal, 1893 P3 center, V3 rotAxis, float degrees, M3 rotationMatrix, 1894 float zoom, float xTrans, float yTrans, 1895 float rotationRadius, P3 navCenter, float xNav, float yNav, 1896 float navDepth, float cameraDepth, float cameraX, 1897 float cameraY) { 1898 // from StateManager -- -1 for time --> no repaint 1899 if (!haveDisplay) 1900 floatSecondsTotal = 0; 1901 setTainted(true); 1902 tm.moveTo(eval, floatSecondsTotal, center, rotAxis, degrees, rotationMatrix, 1903 zoom, xTrans, yTrans, rotationRadius, navCenter, xNav, yNav, navDepth, 1904 cameraDepth, cameraX, cameraY); 1905 } 1906 moveUpdate(float floatSecondsTotal)1907 public void moveUpdate(float floatSecondsTotal) { 1908 if (floatSecondsTotal > 0) 1909 requestRepaintAndWait("moveUpdate"); 1910 else if (floatSecondsTotal == 0) 1911 setSync(); 1912 } 1913 navigatePt(P3 center)1914 public void navigatePt(P3 center) { 1915 // isosurface setHeading 1916 tm.setNavigatePt(center); 1917 setSync(); 1918 } 1919 navigateAxis(V3 rotAxis, float degrees)1920 public void navigateAxis(V3 rotAxis, float degrees) { 1921 // isosurface setHeading 1922 tm.navigateAxis(rotAxis, degrees); 1923 setSync(); 1924 } 1925 navTranslatePercent(float x, float y)1926 public void navTranslatePercent(float x, float y) { 1927 if (isJmolDataFrame()) 1928 return; 1929 tm.navTranslatePercentOrTo(0, x, y); 1930 setSync(); 1931 } 1932 zoomBy(int pixels)1933 void zoomBy(int pixels) { 1934 // MouseManager.mouseSinglePressDrag 1935 //if (mouseEnabled) 1936 tm.zoomBy(pixels); 1937 refresh(REFRESH_SYNC, sm.syncingMouse ? "Mouse: zoomBy " + pixels : ""); 1938 } 1939 zoomByFactor(float factor, int x, int y)1940 void zoomByFactor(float factor, int x, int y) { 1941 // MouseManager.mouseWheel 1942 //if (mouseEnabled) 1943 tm.zoomByFactor(factor, x, y); 1944 refresh(REFRESH_SYNC, 1945 !sm.syncingMouse ? "" 1946 : "Mouse: zoomByFactor " + factor 1947 + (x == Integer.MAX_VALUE ? "" : " " + x + " " + y)); 1948 } 1949 rotateXYBy(float degX, float degY)1950 void rotateXYBy(float degX, float degY) { 1951 // mouseSinglePressDrag 1952 //if (mouseEnabled) 1953 tm.rotateXYBy(degX, degY, null); 1954 refresh(REFRESH_SYNC, 1955 sm.syncingMouse ? "Mouse: rotateXYBy " + degX + " " + degY : ""); 1956 } 1957 spinXYBy(int xDelta, int yDelta, float speed)1958 public void spinXYBy(int xDelta, int yDelta, float speed) { 1959 //if (mouseEnabled) 1960 tm.spinXYBy(xDelta, yDelta, speed); 1961 if (xDelta == 0 && yDelta == 0) 1962 return; 1963 refresh(REFRESH_SYNC, 1964 sm.syncingMouse 1965 ? "Mouse: spinXYBy " + xDelta + " " + yDelta + " " + speed 1966 : ""); 1967 } 1968 rotateZBy(int zDelta, int x, int y)1969 public void rotateZBy(int zDelta, int x, int y) { 1970 // mouseSinglePressDrag 1971 //if (mouseEnabled) 1972 tm.rotateZBy(zDelta, x, y); 1973 refresh(REFRESH_SYNC, 1974 sm.syncingMouse 1975 ? "Mouse: rotateZBy " + zDelta 1976 + (x == Integer.MAX_VALUE ? "" : " " + x + " " + y) 1977 : ""); 1978 } 1979 rotateSelected(float deltaX, float deltaY, BS bsSelected)1980 void rotateSelected(float deltaX, float deltaY, BS bsSelected) { 1981 // bsSelected null comes from sync. 1982 if (isJmolDataFrame()) 1983 return; 1984 //if (mouseEnabled) { 1985 // "true" in setMovableBitSet call is necessary to implement set allowMoveAtoms 1986 tm.rotateXYBy(deltaX, deltaY, setMovableBitSet(bsSelected, true)); 1987 refreshMeasures(true); 1988 //} 1989 //TODO: note that sync may not work with set allowRotateSelectedAtoms 1990 refresh(REFRESH_SYNC, 1991 sm.syncingMouse ? "Mouse: rotateMolecule " + deltaX + " " + deltaY 1992 : ""); 1993 } 1994 1995 public BS movableBitSet; 1996 setMovableBitSet(BS bsSelected, boolean checkMolecule)1997 private BS setMovableBitSet(BS bsSelected, boolean checkMolecule) { 1998 if (bsSelected == null) 1999 bsSelected = bsA(); 2000 bsSelected = BSUtil.copy(bsSelected); 2001 BSUtil.andNot(bsSelected, getMotionFixedAtoms()); 2002 if (checkMolecule && !g.allowMoveAtoms) 2003 bsSelected = ms.getMoleculeBitSet(bsSelected); 2004 return movableBitSet = bsSelected; 2005 } 2006 translateXYBy(int xDelta, int yDelta)2007 public void translateXYBy(int xDelta, int yDelta) { 2008 // mouseDoublePressDrag, mouseSinglePressDrag 2009 //if (mouseEnabled) 2010 tm.translateXYBy(xDelta, yDelta); 2011 refresh(REFRESH_SYNC, 2012 sm.syncingMouse ? "Mouse: translateXYBy " + xDelta + " " + yDelta : ""); 2013 } 2014 2015 @Override rotateFront()2016 public void rotateFront() { 2017 // deprecated 2018 tm.resetRotation(); 2019 refresh(REFRESH_REPAINT, "Viewer:rotateFront()"); 2020 } 2021 translate(char xyz, float x, char type, BS bsAtoms)2022 public void translate(char xyz, float x, char type, BS bsAtoms) { 2023 int xy = (type == '\0' ? (int) x 2024 : type == '%' ? tm.percentToPixels(xyz, x) 2025 : tm.angstromsToPixels(x * (type == 'n' ? 10f : 1f))); 2026 if (bsAtoms != null) { 2027 if (xy == 0) 2028 return; 2029 tm.setSelectedTranslation(bsAtoms, xyz, xy); 2030 } else { 2031 switch (xyz) { 2032 case 'X': 2033 case 'x': 2034 if (type == '\0') 2035 tm.translateToPercent('x', x); 2036 else 2037 tm.translateXYBy(xy, 0); 2038 break; 2039 case 'Y': 2040 case 'y': 2041 if (type == '\0') 2042 tm.translateToPercent('y', x); 2043 else 2044 tm.translateXYBy(0, xy); 2045 break; 2046 case 'Z': 2047 case 'z': 2048 if (type == '\0') 2049 tm.translateToPercent('z', x); 2050 else 2051 tm.translateZBy(xy); 2052 break; 2053 } 2054 } 2055 refresh(REFRESH_REPAINT, "Viewer:translate()"); 2056 } 2057 slabByPixels(int pixels)2058 void slabByPixels(int pixels) { 2059 // MouseManager.mouseSinglePressDrag 2060 tm.slabByPercentagePoints(pixels); 2061 refresh(REFRESH_SYNC_MASK, "slabByPixels"); 2062 } 2063 depthByPixels(int pixels)2064 void depthByPixels(int pixels) { 2065 // MouseManager.mouseDoublePressDrag 2066 tm.depthByPercentagePoints(pixels); 2067 refresh(REFRESH_SYNC_MASK, "depthByPixels"); 2068 2069 } 2070 slabDepthByPixels(int pixels)2071 void slabDepthByPixels(int pixels) { 2072 // MouseManager.mouseSinglePressDrag 2073 tm.slabDepthByPercentagePoints(pixels); 2074 refresh(REFRESH_SYNC_MASK, "slabDepthByPixels"); 2075 } 2076 2077 // @Override 2078 // public M4 getUnscaledTransformMatrix() { 2079 // // unused 2080 // return tm.getUnscaledTransformMatrix(); 2081 // } 2082 finalizeTransformParameters()2083 public void finalizeTransformParameters() { 2084 // FrameRenderer 2085 // InitializeModel 2086 2087 tm.finalizeTransformParameters(); 2088 gdata.setSlabAndZShade(tm.slabValue, tm.depthValue, 2089 (tm.zShadeEnabled ? tm.zSlabValue : Integer.MAX_VALUE), tm.zDepthValue, 2090 g.zShadePower); 2091 } 2092 getScalePixelsPerAngstrom(boolean asAntialiased)2093 public float getScalePixelsPerAngstrom(boolean asAntialiased) { 2094 return tm.scalePixelsPerAngstrom 2095 * (asAntialiased || !antialiased ? 1f : 0.5f); 2096 } 2097 setSpin(String key, int value)2098 public void setSpin(String key, int value) { 2099 // Eval 2100 if (!PT.isOneOf(key, ";x;y;z;fps;X;Y;Z;FPS;")) 2101 return; 2102 int i = "x;y;z;fps;X;Y;Z;FPS".indexOf(key); 2103 switch (i) { 2104 case 0: 2105 tm.setSpinXYZ(value, Float.NaN, Float.NaN); 2106 break; 2107 case 2: 2108 tm.setSpinXYZ(Float.NaN, value, Float.NaN); 2109 break; 2110 case 4: 2111 tm.setSpinXYZ(Float.NaN, Float.NaN, value); 2112 break; 2113 case 6: 2114 default: 2115 tm.setSpinFps(value); 2116 break; 2117 case 10: 2118 tm.setNavXYZ(value, Float.NaN, Float.NaN); 2119 break; 2120 case 12: 2121 tm.setNavXYZ(Float.NaN, value, Float.NaN); 2122 break; 2123 case 14: 2124 tm.setNavXYZ(Float.NaN, Float.NaN, value); 2125 break; 2126 case 16: 2127 tm.setNavFps(value); 2128 break; 2129 } 2130 g.setI((i < 10 ? "spin" : "nav") + key, value); 2131 } 2132 getSpinState()2133 public String getSpinState() { 2134 return getStateCreator().getSpinState(false); 2135 } 2136 2137 /** 2138 * 2139 * @param type 2140 * @param name 2141 * @param bs 2142 * @return String or Quat or P3[] 2143 */ getOrientationText(int type, String name, BS bs)2144 public Object getOrientationText(int type, String name, BS bs) { 2145 switch (type) { 2146 case T.volume: 2147 case T.unitcell: 2148 case T.best: 2149 case T.x: 2150 case T.y: 2151 case T.z: 2152 case T.quaternion: 2153 if (bs == null) 2154 bs = bsA(); 2155 if (bs.isEmpty()) 2156 return (type == T.volume ? "0" 2157 : type == T.unitcell ? null : new Quat()); 2158 Object q = ms.getBoundBoxOrientation(type, bs); 2159 return (name == "best" && type != T.volume 2160 ? ((Quat) q).div(tm.getRotationQ()) 2161 : q); 2162 case T.name: 2163 return stm.getSavedOrientationText(name); 2164 default: 2165 return tm.getOrientationText(type, name == "best"); 2166 } 2167 } 2168 2169 // /////////////////////////////////////////////////////////////// 2170 // delegated to ColorManager 2171 // /////////////////////////////////////////////////////////////// 2172 getCurrentColorRange()2173 public float[] getCurrentColorRange() { 2174 return cm.getPropertyColorRange(); 2175 } 2176 setDefaultColors(boolean isRasmol)2177 private void setDefaultColors(boolean isRasmol) { 2178 cm.setDefaultColors(isRasmol); 2179 g.setB("colorRasmol", isRasmol); 2180 g.setO("defaultColorScheme", (isRasmol ? "rasmol" : "jmol")); 2181 } 2182 setElementArgb(int elementNumber, int argb)2183 public void setElementArgb(int elementNumber, int argb) { 2184 // Eval 2185 g.setO("=color " + Elements.elementNameFromNumber(elementNumber), 2186 Escape.escapeColor(argb)); 2187 cm.setElementArgb(elementNumber, argb); 2188 } 2189 2190 @Override setVectorScale(float scale)2191 public void setVectorScale(float scale) { 2192 g.setF("vectorScale", scale); 2193 g.vectorScale = scale; 2194 } 2195 2196 @Override setVibrationScale(float scale)2197 public void setVibrationScale(float scale) { 2198 // Eval 2199 // public legacy in JmolViewer 2200 tm.setVibrationScale(scale); 2201 g.vibrationScale = scale; 2202 // because this is public: 2203 g.setF("vibrationScale", scale); 2204 } 2205 2206 @Override setVibrationPeriod(float period)2207 public void setVibrationPeriod(float period) { 2208 // Eval 2209 tm.setVibrationPeriod(period); 2210 period = Math.abs(period); 2211 g.vibrationPeriod = period; 2212 // because this is public: 2213 g.setF("vibrationPeriod", period); 2214 } 2215 setObjectColor(String name, String colorName)2216 void setObjectColor(String name, String colorName) { 2217 if (colorName == null || colorName.length() == 0) 2218 return; 2219 setObjectArgb(name, CU.getArgbFromString(colorName)); 2220 } 2221 setObjectVisibility(String name, boolean b)2222 public void setObjectVisibility(String name, boolean b) { 2223 int objId = StateManager.getObjectIdFromName(name); 2224 if (objId >= 0) { 2225 setShapeProperty(objId, "display", b ? Boolean.TRUE : Boolean.FALSE); 2226 } 2227 2228 } 2229 setObjectArgb(String name, int argb)2230 public void setObjectArgb(String name, int argb) { 2231 int objId = StateManager.getObjectIdFromName(name); 2232 if (objId < 0) { 2233 if (name.equalsIgnoreCase("axes")) { 2234 setObjectArgb("axis1", argb); 2235 setObjectArgb("axis2", argb); 2236 setObjectArgb("axis3", argb); 2237 } 2238 return; 2239 } 2240 g.objColors[objId] = argb; 2241 switch (objId) { 2242 case StateManager.OBJ_BACKGROUND: 2243 gdata.setBackgroundArgb(argb); 2244 cm.setColixBackgroundContrast(argb); 2245 break; 2246 } 2247 g.setO(name + "Color", Escape.escapeColor(argb)); 2248 } 2249 setBackgroundImage(String fileName, Object image)2250 public void setBackgroundImage(String fileName, Object image) { 2251 g.backgroundImageFileName = fileName; 2252 gdata.setBackgroundImage(image); 2253 } 2254 getObjectColix(int objId)2255 public short getObjectColix(int objId) { 2256 int argb = g.objColors[objId]; 2257 return (argb == 0 ? cm.colixBackgroundContrast : C.getColix(argb)); 2258 } 2259 2260 // for historical reasons, leave these two: 2261 2262 @Override setColorBackground(String colorName)2263 public void setColorBackground(String colorName) { 2264 setObjectColor("background", colorName); 2265 } 2266 2267 @Override getBackgroundArgb()2268 public int getBackgroundArgb() { 2269 return g.objColors[(StateManager.OBJ_BACKGROUND)]; 2270 } 2271 2272 /** 2273 * input here is a JC.SHAPE_xxxx identifier 2274 * 2275 * @param iShape 2276 * @param name 2277 * @param mad10 2278 */ setObjectMad10(int iShape, String name, int mad10)2279 public void setObjectMad10(int iShape, String name, int mad10) { 2280 int objId = StateManager 2281 .getObjectIdFromName(name.equalsIgnoreCase("axes") ? "axis" : name); 2282 if (objId < 0) 2283 return; 2284 if (mad10 == -2 || mad10 == -4) { // turn on if not set "showAxes = true" 2285 int m = mad10 + 3; 2286 mad10 = getObjectMad10(objId); 2287 if (mad10 == 0) 2288 mad10 = m; 2289 } 2290 g.setB("show" + name, mad10 != 0); 2291 g.objStateOn[objId] = (mad10 != 0); 2292 if (mad10 == 0) 2293 return; 2294 g.objMad10[objId] = mad10; 2295 setShapeSize(iShape, mad10, null); // just loads it 2296 } 2297 2298 /** 2299 * 2300 * @param objId 2301 * @return mad10 2302 */ getObjectMad10(int objId)2303 public int getObjectMad10(int objId) { 2304 return (g.objStateOn[objId] ? g.objMad10[objId] : 0); 2305 } 2306 setPropertyColorScheme(String scheme, boolean isTranslucent, boolean isOverloaded)2307 public void setPropertyColorScheme(String scheme, boolean isTranslucent, 2308 boolean isOverloaded) { 2309 g.propertyColorScheme = scheme; 2310 if (scheme.startsWith("translucent ")) { 2311 isTranslucent = true; 2312 scheme = scheme.substring(12).trim(); 2313 } 2314 cm.setPropertyColorScheme(scheme, isTranslucent, isOverloaded); 2315 } 2316 getLightingState()2317 public String getLightingState() { 2318 return getStateCreator().getLightingState(true); 2319 } 2320 getColorPointForPropertyValue(float val)2321 public P3 getColorPointForPropertyValue(float val) { 2322 // x = {atomno=3}.partialcharge.color 2323 return CU.colorPtFromInt(gdata.getColorArgbOrGray(cm.ce.getColorIndex(val)), 2324 null); 2325 } 2326 2327 // /////////////////////////////////////////////////////////////// 2328 // delegated to SelectionManager 2329 // /////////////////////////////////////////////////////////////// 2330 select(BS bs, boolean isGroup, int addRemove, boolean isQuiet)2331 public void select(BS bs, boolean isGroup, int addRemove, boolean isQuiet) { 2332 // Eval, ActionManager 2333 if (isGroup) 2334 bs = getUndeletedGroupAtomBits(bs); 2335 slm.select(bs, addRemove, isQuiet); 2336 shm.setShapeSizeBs(JC.SHAPE_STICKS, Integer.MAX_VALUE, null, null); 2337 } 2338 2339 @Override setSelectionSet(BS set)2340 public void setSelectionSet(BS set) { 2341 select(set, false, 0, true); 2342 } 2343 selectBonds(BS bs)2344 public void selectBonds(BS bs) { 2345 shm.setShapeSizeBs(JC.SHAPE_STICKS, Integer.MAX_VALUE, null, bs); 2346 } 2347 displayAtoms(BS bs, boolean isDisplay, boolean isGroup, int addRemove, boolean isQuiet)2348 public void displayAtoms(BS bs, boolean isDisplay, boolean isGroup, 2349 int addRemove, boolean isQuiet) { 2350 // Eval 2351 if (isGroup) 2352 bs = getUndeletedGroupAtomBits(bs); 2353 if (isDisplay) 2354 slm.display(ms, bs, addRemove, isQuiet); 2355 else 2356 slm.hide(ms, bs, addRemove, isQuiet); 2357 } 2358 getUndeletedGroupAtomBits(BS bs)2359 private BS getUndeletedGroupAtomBits(BS bs) { 2360 bs = ms.getAtoms(T.group, bs); 2361 BSUtil.andNot(bs, slm.bsDeleted); 2362 return bs; 2363 } 2364 reportSelection(String msg)2365 void reportSelection(String msg) { 2366 if (selectionHalosEnabled) 2367 setTainted(true); 2368 if (isScriptQueued() || g.debugScript) 2369 scriptStatus(msg); 2370 } 2371 clearAtomSets()2372 private void clearAtomSets() { 2373 slm.setSelectionSubset(null); 2374 definedAtomSets.clear(); 2375 if (haveDisplay) 2376 acm.exitMeasurementMode("clearAtomSets"); 2377 } 2378 getDefinedAtomSet(String name)2379 public BS getDefinedAtomSet(String name) { 2380 Object o = definedAtomSets.get(name.toLowerCase()); 2381 return (o instanceof BS ? (BS) o : new BS()); 2382 } 2383 2384 @Override selectAll()2385 public void selectAll() { 2386 // initializeModel 2387 slm.selectAll(false); 2388 } 2389 2390 @Override clearSelection()2391 public void clearSelection() { 2392 // not used in this project; in jmolViewer interface, though 2393 slm.clearSelection(true); 2394 g.setB("hideNotSelected", false); 2395 } 2396 bsA()2397 public BS bsA() { 2398 return slm.getSelectedAtoms(); 2399 } 2400 2401 @Override addSelectionListener(JmolSelectionListener listener)2402 public void addSelectionListener(JmolSelectionListener listener) { 2403 slm.addListener(listener); 2404 } 2405 2406 @Override removeSelectionListener(JmolSelectionListener listener)2407 public void removeSelectionListener(JmolSelectionListener listener) { 2408 slm.addListener(listener); 2409 } 2410 getAtomBitSetEval(JmolScriptEvaluator eval, Object atomExpression)2411 BS getAtomBitSetEval(JmolScriptEvaluator eval, Object atomExpression) { 2412 return (allowScripting 2413 ? getScriptManager().getAtomBitSetEval(eval, atomExpression) 2414 : new BS()); 2415 } 2416 2417 // /////////////////////////////////////////////////////////////// 2418 // delegated to Mouse (part of the apiPlatform system), 2419 // /////////////////////////////////////////////////////////////// 2420 2421 /** 2422 * either org.jmol.awt.Mouse or org.jmol.awtjs2d.Mouse 2423 */ 2424 private GenericMouseInterface mouse; 2425 processTwoPointGesture(float[][][] touches)2426 public void processTwoPointGesture(float[][][] touches) { 2427 mouse.processTwoPointGesture(touches); 2428 } 2429 processMouseEvent(int id, int x, int y, int modifiers, long time)2430 public boolean processMouseEvent(int id, int x, int y, int modifiers, 2431 long time) { 2432 // also used for JavaScript from jQuery 2433 return mouse.processEvent(id, x, y, modifiers, time); 2434 } 2435 2436 // /////////////////////////////////////////////////////////////// 2437 // delegated to ActionManager 2438 // /////////////////////////////////////////////////////////////// 2439 getRubberBandSelection()2440 public Rectangle getRubberBandSelection() { 2441 return (haveDisplay ? acm.getRubberBand() : null); 2442 } 2443 isBound(int mouseAction, int jmolAction)2444 public boolean isBound(int mouseAction, int jmolAction) { 2445 return (haveDisplay && acm.bnd(mouseAction, jmolAction)); 2446 2447 } 2448 getCursorX()2449 public int getCursorX() { 2450 return (haveDisplay ? acm.getCurrentX() : 0); 2451 } 2452 getCursorY()2453 public int getCursorY() { 2454 return (haveDisplay ? acm.getCurrentY() : 0); 2455 } 2456 2457 // /////////////////////////////////////////////////////////////// 2458 // delegated to FileManager 2459 // /////////////////////////////////////////////////////////////// 2460 getDefaultDirectory()2461 public String getDefaultDirectory() { 2462 return g.defaultDirectory; 2463 } 2464 getLocalUrl(String fileName)2465 public String getLocalUrl(String fileName) { 2466 return apiPlatform.getLocalUrl(fileName); 2467 } 2468 getFileAsString(String fileName)2469 public String getFileAsString(String fileName) { 2470 return getAsciiFileOrNull(fileName); 2471 } 2472 2473 @Override getBufferedInputStream(String fullPathName)2474 public BufferedInputStream getBufferedInputStream(String fullPathName) { 2475 // used by some JVXL readers, also OutputManager.writeZipFile and ScriptManager.openFileAsync 2476 return fm.getBufferedInputStream(fullPathName); 2477 } 2478 setLoadParameters(Map<String, Object> htParams, boolean isAppend)2479 public Map<String, Object> setLoadParameters(Map<String, Object> htParams, 2480 boolean isAppend) { 2481 if (htParams == null) 2482 htParams = new Hashtable<String, Object>(); 2483 htParams.put("vwr", this); 2484 if (g.atomTypes.length() > 0) 2485 htParams.put("atomTypes", g.atomTypes); 2486 if (!htParams.containsKey("lattice")) 2487 htParams.put("lattice", g.ptDefaultLattice); 2488 if (g.applySymmetryToBonds) 2489 htParams.put("applySymmetryToBonds", Boolean.TRUE); 2490 if (g.pdbGetHeader) 2491 htParams.put("getHeader", Boolean.TRUE); 2492 if (g.pdbSequential) 2493 htParams.put("isSequential", Boolean.TRUE); 2494 if (g.legacyJavaFloat) 2495 htParams.put("legacyJavaFloat", Boolean.TRUE); 2496 htParams.put("stateScriptVersionInt", 2497 Integer.valueOf(stateScriptVersionInt)); 2498 if (!htParams.containsKey("filter")) { 2499 String filter = g.defaultLoadFilter; 2500 if (filter.length() > 0) 2501 htParams.put("filter", filter); 2502 } 2503 boolean merging = (isAppend && !g.appendNew && ms.ac > 0); 2504 htParams.put("baseAtomIndex", Integer.valueOf(isAppend ? ms.ac : 0)); 2505 htParams.put("baseBondIndex", Integer.valueOf(isAppend ? ms.bondCount : 0)); 2506 htParams.put("baseModelIndex", 2507 Integer.valueOf(ms.ac == 0 ? 0 : ms.mc + (merging ? -1 : 0))); 2508 if (merging) 2509 htParams.put("merging", Boolean.TRUE); 2510 return htParams; 2511 } 2512 2513 // //////////////// methods that open a file to create a model set /////////// 2514 2515 // *indicates when a refresh is made (external apps and applets only) 2516 // 2517 // external apps only 2518 // via loadInline(List)* 2519 // createModelSetAndReturnError 2520 // 2521 // openDOM, openReader, openFile, openFiles 2522 // via loadModelFromFileRepaint* 2523 // createModelSetAndReturnError 2524 // 2525 // loadInLine(String) via loadInLineScriptRepaint* 2526 // FileDropper (string drop) via openStringInline* 2527 // via openStringInlineParamsAppend 2528 // createModelSetAndReturnError 2529 // 2530 // external apps, applet only, via loadInline(String[])* 2531 // via openStringsInlineParamsAppend 2532 // createModelSetAndReturnError 2533 // 2534 // script LOAD 2535 // via loadModelFromFile 2536 // createModelSetAndReturnError 2537 // 2538 // script CALCULATE HYDROGENS, PLOT, ZAP (modelkit) 2539 // via openStringInlineParamsAppend 2540 // createModelSetAndReturnError 2541 // 2542 // script LOAD DATA via loadFileFull and loadInlineScript 2543 // openStringsInlineParamsAppend 2544 // createModelSetAndReturnError 2545 2546 /** 2547 * opens a file as a model, a script, or a surface via the creation of a 2548 * script that is queued \t at the beginning disallows script option - used by 2549 * JmolFileDropper and JmolPanel file-open actions - sets up a script to load 2550 * the file. 2551 * 2552 * Called from (JSmolCore.js)Jmol.$appEvent(,,"drop").reader.onloadend() 2553 * 2554 * @param fileName 2555 * @param flags 2556 * 1=pdbCartoons, 2=no scripting, 4=append, 8=fileOpen, 16=fileDropped 2557 * 2558 */ 2559 @Override openFileAsyncSpecial(String fileName, int flags)2560 public void openFileAsyncSpecial(String fileName, int flags) { 2561 getScriptManager().openFileAsync(fileName, flags, false); 2562 } 2563 openFileDropped(String fname, boolean checkDims)2564 public void openFileDropped(String fname, boolean checkDims) { 2565 getScriptManager().openFileAsync(fname, JmolScriptManager.FILE_DROPPED, 2566 checkDims); 2567 } 2568 2569 /** 2570 * 2571 * for JmolSimpleViewer -- external applications only (and no-script 2572 * JavaScript) 2573 * 2574 * @param fileName 2575 * @return null or error 2576 */ 2577 @Override openFile(String fileName)2578 public String openFile(String fileName) { 2579 zap(true, true, false); 2580 return loadModelFromFileRepaint(null, fileName, null, null); 2581 } 2582 2583 /** 2584 * for JmolSimpleViewer -- external applications only 2585 * 2586 * @param fileNames 2587 * @return null or error 2588 */ 2589 @Override openFiles(String[] fileNames)2590 public String openFiles(String[] fileNames) { 2591 zap(true, true, false); 2592 return loadModelFromFileRepaint(null, null, fileNames, null); 2593 } 2594 2595 /** 2596 * Opens the file, given an already-created reader. 2597 * 2598 * @param fullPathName 2599 * @param fileName 2600 * name without path or can just be null 2601 * @param reader 2602 * could be Reader, BufferedInputStream, or byte[] 2603 * @return null or error message 2604 */ 2605 @Override openReader(String fullPathName, String fileName, Object reader)2606 public String openReader(String fullPathName, String fileName, 2607 Object reader) { 2608 zap(true, true, false); 2609 return loadModelFromFileRepaint(fullPathName, fileName, null, reader); 2610 } 2611 2612 /** 2613 * applet DOM method -- does not preserve state 2614 * 2615 * @param DOMNode 2616 * @return null or error 2617 * 2618 */ 2619 @Override openDOM(Object DOMNode)2620 public String openDOM(Object DOMNode) { 2621 // applet.loadDOMNode 2622 zap(true, true, false); 2623 return loadModelFromFileRepaint("?", "?", null, DOMNode); 2624 } 2625 2626 /** 2627 * 2628 * for JmolSimpleViewer -- external applications only (and no-script 2629 * JavaScript) 2630 * 2631 * @param fullPathName 2632 * @param fileName 2633 * @param fileNames 2634 * @param reader 2635 * @return error message or null 2636 * 2637 */ loadModelFromFileRepaint(String fullPathName, String fileName, String[] fileNames, Object reader)2638 private String loadModelFromFileRepaint(String fullPathName, String fileName, 2639 String[] fileNames, Object reader) { 2640 String ret = loadModelFromFile(fullPathName, fileName, fileNames, reader, 2641 false, null, null, null, 0, " "); 2642 refresh(REFRESH_REPAINT, "loadModelFromFileRepaint"); 2643 return ret; 2644 } 2645 2646 /** 2647 * Used by the ScriptEvaluator LOAD command to open one or more files. Now 2648 * necessary for EVERY load of a file, as loadScript must be passed to the 2649 * ModelLoader. 2650 * 2651 * @param fullPathName 2652 * may be null; used only when reader != null 2653 * @param fileName 2654 * must not be null 2655 * @param fileNames 2656 * when present, reader is ignored 2657 * @param reader 2658 * may be a Reader, BufferedReader, byte[], or BufferedInputStream 2659 * @param isAppend 2660 * @param htParams 2661 * @param loadScript 2662 * @param sOptions 2663 * @param tokType 2664 * @param filecat 2665 * + or null, -, or space 2666 * @return null or error 2667 */ loadModelFromFile(String fullPathName, String fileName, String[] fileNames, Object reader, boolean isAppend, Map<String, Object> htParams, SB loadScript, SB sOptions, int tokType, String filecat)2668 public String loadModelFromFile(String fullPathName, String fileName, 2669 String[] fileNames, Object reader, 2670 boolean isAppend, 2671 Map<String, Object> htParams, SB loadScript, 2672 SB sOptions, int tokType, String filecat) { 2673 if (htParams == null) 2674 htParams = setLoadParameters(null, isAppend); 2675 if (tokType != T.nada) 2676 htParams.put("dataType", T.nameOf(tokType)); 2677 if (filecat != " ") 2678 htParams.put("concatenate", Boolean.TRUE); 2679 Object atomSetCollection; 2680 String[] saveInfo = fm.getFileInfo(); 2681 2682 // testing only reader = fm.getFileAsBytes(fileName, null); 2683 if (fileNames != null) { 2684 2685 // 1) a set of file names 2686 2687 if (loadScript == null) { 2688 loadScript = new SB().append("load files"); 2689 for (int i = 0; i < fileNames.length; i++) 2690 loadScript.append(i == 0 || filecat == null ? " " : filecat) 2691 .append("/*file*/$FILENAME" + (i + 1) + "$"); 2692 if (sOptions.length() > 0) 2693 loadScript.append(" /*options*/ ").append(sOptions.toString()); 2694 } 2695 long timeBegin = System.currentTimeMillis(); 2696 2697 atomSetCollection = fm.createAtomSetCollectionFromFiles(fileNames, 2698 setLoadParameters(htParams, isAppend), isAppend); 2699 long ms = System.currentTimeMillis() - timeBegin; 2700 Logger.info("openFiles(" + fileNames.length + ") " + ms + " ms"); 2701 fileNames = (String[]) htParams.get("fullPathNames"); 2702 String[] fileTypes = (String[]) htParams.get("fileTypes"); 2703 String s = loadScript.toString(); 2704 for (int i = 0; i < fileNames.length; i++) { 2705 String fname = fileNames[i]; 2706 if (fileTypes != null && fileTypes[i] != null) 2707 fname = fileTypes[i] + "::" + fname; 2708 s = PT.rep(s, "$FILENAME" + (i + 1) + "$", 2709 PT.esc(FileManager.fixDOSName(fname))); 2710 } 2711 2712 loadScript = new SB().append(s); 2713 2714 } else if (reader == null) { 2715 2716 // 2) a standard, single file 2717 2718 if (loadScript == null) 2719 loadScript = new SB().append("load /*file*/$FILENAME$"); 2720 2721 atomSetCollection = openFileFull(fileName, isAppend, htParams, 2722 loadScript); 2723 2724 } else if (reader instanceof Reader || reader instanceof BufferedInputStream 2725 || AU.isAB(reader)) { 2726 2727 // 3) a file reader, BufferedInputStream, or byte[] (not used by Jmol) 2728 2729 atomSetCollection = fm.createAtomSetCollectionFromReader(fullPathName, 2730 fileName, reader, setLoadParameters(htParams, isAppend)); 2731 2732 } else { 2733 2734 // 4) a DOM reader (could be used by Jmol) 2735 2736 atomSetCollection = fm.createAtomSetCollectionFromDOM(reader, 2737 setLoadParameters(htParams, isAppend)); 2738 2739 } 2740 2741 // OK, the file has been read and is now closed. 2742 2743 if (tokType != 0) { // all we are doing is reading atom data 2744 fm.setFileInfo(saveInfo); 2745 return loadAtomDataAndReturnError(atomSetCollection, tokType); 2746 } 2747 2748 if (htParams.containsKey("isData")) 2749 return (String) atomSetCollection; 2750 2751 // now we fix the load script (possibly) with the full path name 2752 if (loadScript != null && !(atomSetCollection instanceof String)) { 2753 String fname = (String) htParams.get("fullPathName"); 2754 if (fname == null) 2755 fname = ""; 2756 // may have been modified. 2757 if (htParams.containsKey("loadScript")) 2758 loadScript = (SB) htParams.get("loadScript"); 2759 htParams.put("loadScript", 2760 loadScript = new SB().append(javajs.util.PT.rep(loadScript.toString(), 2761 "$FILENAME$", PT.esc(FileManager.fixDOSName(fname))))); 2762 } 2763 2764 // and finally to create the model set... 2765 2766 return createModelSetAndReturnError(atomSetCollection, isAppend, loadScript, 2767 htParams); 2768 } 2769 2770 Map<String, Object> ligandModels; 2771 Map<String, Boolean> ligandModelSet; 2772 setLigandModel(String key, String data)2773 public void setLigandModel(String key, String data) { 2774 if (ligandModels == null) 2775 ligandModels = new Hashtable<String, Object>(); 2776 ligandModels.put(key, data); 2777 } 2778 2779 /** 2780 * obtain CIF data for a ligand for purposes of adding hydrogens or for any 2781 * other purpose in terms of saving a data set for a file in a state 2782 * 2783 * @param id 2784 * unique key; if null, clear "bad" entries from the set. 2785 * @param prefix 2786 * @param suffix 2787 * or fileName 2788 * @param terminator 2789 * Only save to this if not null 2790 * @return a ligand model or a string if just file data or null 2791 */ getLigandModel(String id, String prefix, String suffix, String terminator)2792 public Object getLigandModel(String id, String prefix, String suffix, 2793 String terminator) { 2794 // getLigandModel(id, m40File, "_file", "----")); 2795 // getLigandModel(group3, "ligand_", "_data", null); 2796 if (id == null) { 2797 if (ligandModelSet != null) { 2798 Iterator<Map.Entry<String, Object>> e = ligandModels.entrySet() 2799 .iterator(); 2800 while (e.hasNext()) { 2801 Entry<String, Object> entry = e.next(); 2802 if (entry.getValue() instanceof Boolean) 2803 e.remove(); 2804 } 2805 } 2806 return null; 2807 } 2808 id = id.replace('\\', '/'); 2809 boolean isLigand = prefix.equals("ligand_"); 2810 id = (id.indexOf("/cif") >= 0 ? id 2811 : isLigand ? id.toUpperCase() : id.substring(id.lastIndexOf("/") + 1)); 2812 if (ligandModelSet == null) 2813 ligandModelSet = new Hashtable<String, Boolean>(); 2814 ligandModelSet.put(id, Boolean.TRUE); 2815 if (ligandModels == null) 2816 ligandModels = new Hashtable<String, Object>(); 2817 int pngPt = id.indexOf("|"); 2818 if (pngPt >= 0) 2819 id = id.substring(id.indexOf("|") + 1); 2820 Object model = (terminator == null ? ligandModels.get(id) : null); 2821 String data; 2822 String fname = null; 2823 if (model instanceof Boolean) 2824 return null; 2825 if (model == null && (terminator == null || pngPt >= 0)) 2826 model = ligandModels.get(id + suffix); 2827 boolean isError = false; 2828 boolean isNew = (model == null); 2829 if (isNew) { 2830 String s; 2831 if (isLigand) { 2832 fname = (String) setLoadFormat("#" + id, '#', false); 2833 if (fname.length() == 0) 2834 return null; 2835 scriptEcho("fetching " + fname); 2836 s = getFileAsString3(fname, false, null); 2837 } else { 2838 scriptEcho("fetching " + prefix); 2839 s = getFileAsString3(prefix, false, null); 2840 int pt = (terminator == null ? -1 : s.indexOf(terminator)); 2841 if (pt >= 0) 2842 s = s.substring(0, pt); 2843 } 2844 isError = (s.indexOf("java.") == 0); 2845 model = s; 2846 if (!isError) 2847 ligandModels.put(id + suffix, model); 2848 } 2849 if (!isLigand) { 2850 if (!isNew) 2851 scriptEcho(prefix + " loaded from cache"); 2852 return model; 2853 } 2854 // process ligand business 2855 2856 if (!isError && model instanceof String) { 2857 data = (String) model; 2858 // TODO: check for errors in reading file 2859 if (data.length() != 0) { 2860 Map<String, Object> htParams = new Hashtable<String, Object>(); 2861 htParams.put("modelOnly", Boolean.TRUE); 2862 model = getModelAdapter().getAtomSetCollectionReader("ligand", null, 2863 Rdr.getBR(data), htParams); 2864 isError = (model instanceof String); 2865 if (!isError) { 2866 model = getModelAdapter().getAtomSetCollection(model); 2867 isError = (model instanceof String); 2868 if (fname != null && !isError) 2869 scriptEcho((String) getModelAdapter() 2870 .getAtomSetCollectionAuxiliaryInfo(model).get("modelLoadNote")); 2871 } 2872 } 2873 } 2874 if (isError) { 2875 scriptEcho(model.toString()); 2876 ligandModels.put(id, Boolean.FALSE); 2877 return null; 2878 } 2879 return model; 2880 } 2881 2882 /** 2883 * 2884 * does NOT repaint 2885 * 2886 * @param fileName 2887 * @param isAppend 2888 * @param htParams 2889 * @param loadScript 2890 * only necessary for string reading 2891 * @return an AtomSetCollection or a String (error) 2892 */ openFileFull(String fileName, boolean isAppend, Map<String, Object> htParams, SB loadScript)2893 private Object openFileFull(String fileName, boolean isAppend, 2894 Map<String, Object> htParams, SB loadScript) { 2895 if (fileName == null) 2896 return null; 2897 if (fileName.equals("String[]")) { 2898 // no reloading of string[] or file[] data -- just too complicated 2899 return null; 2900 } 2901 Object atomSetCollection; 2902 String msg = "openFile(" + fileName + ")"; 2903 Logger.startTimer(msg); 2904 htParams = setLoadParameters(htParams, isAppend); 2905 boolean isLoadVariable = fileName.startsWith("@"); 2906 boolean haveFileData = (htParams.containsKey("fileData")); 2907 if (fileName.indexOf('$') == 0) 2908 htParams.put("smilesString", fileName.substring(1)); 2909 boolean isString = (fileName.equals("string") 2910 || fileName.equals(JC.MODELKIT_ZAP_TITLE)); 2911 String strModel = null; 2912 if (haveFileData) { 2913 strModel = (String) htParams.get("fileData"); 2914 if (htParams.containsKey("isData")) { 2915 Object o = loadInlineScript(strModel, '\0', isAppend, htParams); 2916 lastData = (g.preserveState ? getDataManager().createFileData(strModel) 2917 : null); 2918 return o; 2919 } 2920 } else if (isString) { 2921 strModel = ms.getInlineData(-1); 2922 if (strModel == null) 2923 if (g.modelKitMode) 2924 strModel = JC.MODELKIT_ZAP_STRING; 2925 else 2926 return "cannot find string data"; 2927 if (loadScript != null) 2928 htParams.put("loadScript", 2929 loadScript = new SB().append(PT.rep(loadScript.toString(), 2930 "/*file*/$FILENAME$", "/*data*/data \"model inline\"\n" 2931 + strModel + "end \"model inline\""))); 2932 } 2933 if (strModel != null) { 2934 if (!isAppend) 2935 zap(true, false/*true*/, false); 2936 if (!isLoadVariable && (!haveFileData || isString)) 2937 getStateCreator().getInlineData(loadScript, strModel, isAppend, 2938 (Integer) htParams.get("appendToModelIndex"), 2939 g.defaultLoadFilter); 2940 atomSetCollection = fm.createAtomSetCollectionFromString(strModel, 2941 htParams, isAppend); 2942 } else { 2943 2944 // if the filename has a "?" at the beginning, we don't zap, 2945 // because the user might cancel the operation. 2946 2947 atomSetCollection = fm.createAtomSetCollectionFromFile(fileName, htParams, 2948 isAppend); 2949 } 2950 Logger.checkTimer(msg, false); 2951 return atomSetCollection; 2952 } 2953 2954 /** 2955 * only used by file dropper. 2956 */ 2957 2958 @Override openStringInline(String strModel)2959 public String openStringInline(String strModel) { 2960 // JmolSimpleViewer; JmolFileDropper inline string event 2961 String ret = openStringInlineParamsAppend(strModel, null, false); 2962 refresh(REFRESH_REPAINT, "openStringInline"); 2963 return ret; 2964 } 2965 2966 /** 2967 * from Applet and external applications only 2968 */ 2969 2970 @Override loadInline(String strModel)2971 public String loadInline(String strModel) { 2972 // jmolViewer interface 2973 return loadInlineScriptRepaint(strModel, g.inlineNewlineChar, false); 2974 } 2975 2976 /** 2977 * external apps only 2978 * 2979 */ 2980 2981 @Override loadInline(String strModel, char newLine)2982 public String loadInline(String strModel, char newLine) { 2983 // JmolViewer interface 2984 return loadInlineScriptRepaint(strModel, newLine, false); 2985 } 2986 2987 /** 2988 * used by applet and console 2989 */ 2990 2991 @Override loadInlineAppend(String strModel, boolean isAppend)2992 public String loadInlineAppend(String strModel, boolean isAppend) { 2993 // JmolViewer interface 2994 return loadInlineScriptRepaint(strModel, '\0', isAppend); 2995 } 2996 loadInlineScriptRepaint(String strModel, char newLine, boolean isAppend)2997 private String loadInlineScriptRepaint(String strModel, char newLine, 2998 boolean isAppend) { 2999 String ret = loadInlineScript(strModel, newLine, isAppend, null); 3000 refresh(REFRESH_REPAINT, "loadInlineScript"); 3001 return ret; 3002 } 3003 3004 /** 3005 * external apps only 3006 * 3007 */ 3008 3009 @Override loadInline(String[] arrayModels)3010 public String loadInline(String[] arrayModels) { 3011 // JmolViewer interface 3012 return loadInline(arrayModels, false); 3013 } 3014 3015 /** 3016 * external apps and applet only 3017 * 3018 */ 3019 @Override loadInline(String[] arrayModels, boolean isAppend)3020 public String loadInline(String[] arrayModels, boolean isAppend) { 3021 // JmolViewer interface 3022 // Eval data 3023 // loadInline 3024 if (arrayModels == null || arrayModels.length == 0) 3025 return null; 3026 String ret = openStringsInlineParamsAppend(arrayModels, 3027 new Hashtable<String, Object>(), isAppend); 3028 refresh(REFRESH_REPAINT, "loadInline String[]"); 3029 return ret; 3030 } 3031 3032 /** 3033 * External applications only; does not preserve state -- intentionally! 3034 * 3035 * @param arrayData 3036 * @param isAppend 3037 * @return null or error string 3038 * 3039 */ 3040 @Override loadInline(java.util.List<Object> arrayData, boolean isAppend)3041 public String loadInline(java.util.List<Object> arrayData, boolean isAppend) { 3042 // NO STATE SCRIPT -- HERE WE ARE TRYING TO CONSERVE SPACE 3043 3044 // loadInline 3045 if (arrayData == null || arrayData.size() == 0) 3046 return null; 3047 if (!isAppend) 3048 zap(true, false/*true*/, false); 3049 Lst<Object> list = new Lst<Object>(); 3050 for (int i = 0; i < arrayData.size(); i++) 3051 list.addLast(arrayData.get(i)); 3052 Object atomSetCollection = fm.createAtomSeCollectionFromArrayData(list, 3053 setLoadParameters(null, isAppend), isAppend); 3054 String ret = createModelSetAndReturnError(atomSetCollection, isAppend, null, 3055 new Hashtable<String, Object>()); 3056 refresh(REFRESH_REPAINT, "loadInline"); 3057 return ret; 3058 } 3059 3060 /** 3061 * used by loadInline and openFileFull 3062 * 3063 * @param strModel 3064 * @param newLine 3065 * @param isAppend 3066 * @param htParams 3067 * @return null or error message 3068 */ loadInlineScript(String strModel, char newLine, boolean isAppend, Map<String, Object> htParams)3069 private String loadInlineScript(String strModel, char newLine, 3070 boolean isAppend, 3071 Map<String, Object> htParams) { 3072 if (strModel == null || strModel.length() == 0) 3073 return null; 3074 strModel = fixInlineString(strModel, newLine); 3075 if (newLine != 0) 3076 Logger.info("loading model inline, " + strModel.length() 3077 + " bytes, with newLine character " + (int) newLine + " isAppend=" 3078 + isAppend); 3079 if (Logger.debugging) 3080 Logger.debug(strModel); 3081 String datasep = getDataSeparator(); 3082 int i; 3083 if (datasep != null && datasep != "" && (i = strModel.indexOf(datasep)) >= 0 3084 && strModel.indexOf("# Jmol state") < 0) { 3085 int n = 2; 3086 while ((i = strModel.indexOf(datasep, i + 1)) >= 0) 3087 n++; 3088 String[] strModels = new String[n]; 3089 int pt = 0, pt0 = 0; 3090 for (i = 0; i < n; i++) { 3091 pt = strModel.indexOf(datasep, pt0); 3092 if (pt < 0) 3093 pt = strModel.length(); 3094 strModels[i] = strModel.substring(pt0, pt); 3095 pt0 = pt + datasep.length(); 3096 } 3097 return openStringsInlineParamsAppend(strModels, htParams, isAppend); 3098 } 3099 return openStringInlineParamsAppend(strModel, htParams, isAppend); 3100 } 3101 fixInlineString(String strModel, char newLine)3102 public static String fixInlineString(String strModel, char newLine) { 3103 // only if first character is "|" do we consider "|" to be new line 3104 int i; 3105 if (strModel.indexOf("\\/n") >= 0) { 3106 // the problem is that when this string is passed to Jmol 3107 // by the web page <embed> mechanism, browsers differ 3108 // in how they handle CR and LF. Some will pass it, 3109 // some will not. 3110 strModel = PT.rep(strModel, "\n", ""); 3111 strModel = PT.rep(strModel, "\\/n", "\n"); 3112 newLine = 0; 3113 } 3114 if (newLine != 0 && newLine != '\n') { 3115 boolean repEmpty = (strModel.indexOf('\n') >= 0); 3116 int len = strModel.length(); 3117 for (i = 0; i < len && strModel.charAt(i) == ' '; ++i) { 3118 } 3119 if (i < len && strModel.charAt(i) == newLine) 3120 strModel = strModel.substring(i + 1); 3121 if (repEmpty) 3122 strModel = PT.rep(strModel, "" + newLine, ""); 3123 else 3124 strModel = strModel.replace(newLine, '\n'); 3125 } 3126 return strModel; 3127 } 3128 3129 /** 3130 * Only used for adding hydrogen atoms and adding the model kit methane model; 3131 * not part of the public interface. 3132 * 3133 * @param strModel 3134 * @param htParams 3135 * @param isAppend 3136 * @return null or error string 3137 * 3138 */ openStringInlineParamsAppend(String strModel, Map<String, Object> htParams, boolean isAppend)3139 public String openStringInlineParamsAppend(String strModel, 3140 Map<String, Object> htParams, 3141 boolean isAppend) { 3142 // loadInline, openStringInline 3143 3144 String type = getModelAdapter().getFileTypeName(Rdr.getBR(strModel)); 3145 if (type == null) 3146 return "unknown file type"; 3147 if (type.equals("spt")) { 3148 return "cannot open script inline"; 3149 } 3150 3151 htParams = setLoadParameters(htParams, isAppend); 3152 SB loadScript = (SB) htParams.get("loadScript"); 3153 boolean isLoadCommand = htParams.containsKey("isData"); 3154 if (loadScript == null) 3155 loadScript = new SB(); 3156 if (!isAppend) 3157 zap(true, false/*true*/, false); 3158 if (!isLoadCommand) 3159 getStateCreator().getInlineData(loadScript, strModel, isAppend, 3160 (Integer) htParams.get("appendToModelIndex"), g.defaultLoadFilter); 3161 Object atomSetCollection = fm.createAtomSetCollectionFromString(strModel, 3162 htParams, isAppend); 3163 return createModelSetAndReturnError(atomSetCollection, isAppend, loadScript, 3164 htParams); 3165 } 3166 3167 /** 3168 * opens multiple files inline; does NOT repaint 3169 * 3170 * @param arrayModels 3171 * @param htParams 3172 * @param isAppend 3173 * @return null or error message 3174 */ openStringsInlineParamsAppend(String[] arrayModels, Map<String, Object> htParams, boolean isAppend)3175 private String openStringsInlineParamsAppend(String[] arrayModels, 3176 Map<String, Object> htParams, 3177 boolean isAppend) { 3178 // loadInline 3179 SB loadScript = new SB(); 3180 if (!isAppend) 3181 zap(true, false/*true*/, false); 3182 Object atomSetCollection = fm.createAtomSeCollectionFromStrings(arrayModels, 3183 loadScript, setLoadParameters(htParams, isAppend), isAppend); 3184 return createModelSetAndReturnError(atomSetCollection, isAppend, loadScript, 3185 htParams); 3186 } 3187 getInlineChar()3188 public char getInlineChar() { 3189 // used by the ScriptEvaluator DATA command 3190 return g.inlineNewlineChar; 3191 } 3192 getDataSeparator()3193 String getDataSeparator() { 3194 // used to separate data files within a single DATA command 3195 return (String) g.getParameter("dataseparator", true); 3196 } 3197 3198 ////////// create the model set //////////// 3199 3200 /** 3201 * finally(!) we are ready to create the "model set" from the "atom set 3202 * collection" - does NOT repaint 3203 * 3204 * @param atomSetCollection 3205 * @param isAppend 3206 * @param loadScript 3207 * if null, then some special method like DOM; turn of preserveState 3208 * @param htParams 3209 * @return errMsg 3210 */ createModelSetAndReturnError(Object atomSetCollection, boolean isAppend, SB loadScript, Map<String, Object> htParams)3211 private String createModelSetAndReturnError(Object atomSetCollection, 3212 boolean isAppend, SB loadScript, 3213 Map<String, Object> htParams) { 3214 3215 Logger.startTimer("creating model"); 3216 3217 String fullPathName = fm.getFullPathName(false); 3218 String fileName = fm.getFileName(); 3219 String errMsg; 3220 if (loadScript == null) { 3221 setBooleanProperty("preserveState", false); 3222 loadScript = new SB().append("load \"???\""); 3223 } 3224 if (atomSetCollection instanceof String) { 3225 errMsg = (String) atomSetCollection; 3226 setFileLoadStatus(FIL.NOT_LOADED, fullPathName, null, null, errMsg, null); 3227 if (displayLoadErrors && !isAppend && !errMsg.equals("#CANCELED#") 3228 && !errMsg.startsWith(JC.READER_NOT_FOUND)) 3229 zapMsg(errMsg); 3230 return errMsg; 3231 } 3232 if (isAppend) 3233 clearAtomSets(); 3234 else if (g.modelKitMode && !fileName.equals("Jmol Model Kit")) 3235 setModelKitMode(false); 3236 setFileLoadStatus(FIL.CREATING_MODELSET, fullPathName, fileName, null, null, 3237 null); 3238 3239 // null fullPathName implies we are doing a merge 3240 pushHoldRepaintWhy("createModelSet"); 3241 setErrorMessage(null, null); 3242 try { 3243 BS bsNew = new BS(); 3244 mm.createModelSet(fullPathName, fileName, loadScript, atomSetCollection, 3245 bsNew, isAppend); 3246 if (bsNew.cardinality() > 0) { 3247 // is a 2D dataset, as from JME 3248 String jmolScript = (String) ms.getInfoM("jmolscript"); 3249 if (ms.getMSInfoB("doMinimize")) { 3250 try { 3251 JmolScriptEvaluator eval = (JmolScriptEvaluator) htParams 3252 .get("eval"); 3253 BS stereo = getAtomBitSet("_C & connected(3) & !connected(double)"); 3254 stereo.and(bsNew); 3255 if (stereo.nextSetBit(0) >= 0) { 3256 bsNew.or(addHydrogens(stereo,MIN_NO_RANGE | MIN_SILENT | MIN_QUICK)); 3257 } 3258 minimize(eval, Integer.MAX_VALUE, 0, bsNew, null, 0, 3259 MIN_ADDH | MIN_NO_RANGE | MIN_SILENT | MIN_QUICK); 3260 } catch (Exception e) { 3261 } 3262 } else { 3263 addHydrogens(bsNew, MIN_SILENT | MIN_QUICK); 3264 } 3265 // no longer necessary? -- this is the JME/SMILES data: 3266 if (jmolScript != null) 3267 ms.msInfo.put("jmolscript", jmolScript); 3268 } 3269 initializeModel(isAppend); 3270 // if (global.modelkitMode && 3271 // (modelSet.modelCount > 1 || modelSet.models[0].isPDB())) 3272 // setBooleanProperty("modelkitmode", false); 3273 3274 } catch (Error er) { 3275 handleError(er, true); 3276 errMsg = getShapeErrorState(); 3277 errMsg = ("ERROR creating model: " + er 3278 + (errMsg.length() == 0 ? "" : "|" + errMsg)); 3279 zapMsg(errMsg); 3280 setErrorMessage(errMsg, null); 3281 } 3282 popHoldRepaint("createModelSet " + JC.REPAINT_IGNORE); 3283 errMsg = getErrorMessage(); 3284 3285 setFileLoadStatus(FIL.CREATED, fullPathName, fileName, ms.modelSetName, 3286 errMsg, (Boolean) htParams.get("async")); 3287 if (isAppend) { 3288 selectAll(); 3289 setTainted(true); 3290 axesAreTainted = true; 3291 } 3292 atomSetCollection = null; 3293 Logger.checkTimer("creating model", false); 3294 System.gc(); 3295 return errMsg; 3296 } 3297 3298 /** 3299 * 3300 * or just apply the data to the current model set 3301 * 3302 * @param atomSetCollection 3303 * @param tokType 3304 * @return error or null 3305 */ loadAtomDataAndReturnError(Object atomSetCollection, int tokType)3306 private String loadAtomDataAndReturnError(Object atomSetCollection, 3307 int tokType) { 3308 if (atomSetCollection instanceof String) 3309 return (String) atomSetCollection; 3310 setErrorMessage(null, null); 3311 try { 3312 String script = mm.createAtomDataSet(atomSetCollection, tokType); 3313 switch (tokType) { 3314 case T.xyz: 3315 if (script != null) 3316 runScriptCautiously(script); 3317 break; 3318 case T.vibration: 3319 setStatusFrameChanged(true, false); 3320 break; 3321 case T.vanderwaals: 3322 shm.deleteVdwDependentShapes(null); 3323 break; 3324 } 3325 } catch (Error er) { 3326 handleError(er, true); 3327 String errMsg = getShapeErrorState(); 3328 errMsg = ("ERROR adding atom data: " + er 3329 + (errMsg.length() == 0 ? "" : "|" + errMsg)); 3330 zapMsg(errMsg); 3331 setErrorMessage(errMsg, null); 3332 setParallel(false); 3333 } 3334 return getErrorMessage(); 3335 } 3336 3337 ////////// File-related methods //////////// 3338 getCurrentFileAsString(String state)3339 public String getCurrentFileAsString(String state) { 3340 String filename = fm.getFullPathName(false); 3341 if (filename.equals("string") || filename.equals(JC.MODELKIT_ZAP_TITLE)) 3342 return ms.getInlineData(am.cmi); 3343 if (filename.equals("String[]")) 3344 return filename; 3345 if (filename == "JSNode") 3346 return "<DOM NODE>"; 3347 // filename = mm.getModelSetPathName(); 3348 // if (filename == null) 3349 // return null; 3350 return getFileAsString4(filename, -1, true, false, false, state); 3351 } 3352 3353 /** 3354 * 3355 * @param filename 3356 * @return String[2] where [0] is fullpathname and [1] is error message or 3357 * null 3358 */ getFullPathNameOrError(String filename)3359 public String[] getFullPathNameOrError(String filename) { 3360 String[] data = new String[2]; 3361 fm.getFullPathNameOrError(filename, false, data); 3362 return data; 3363 } 3364 getFileAsString3(String name, boolean checkProtected, String state)3365 public String getFileAsString3(String name, boolean checkProtected, 3366 String state) { 3367 return getFileAsString4(name, -1, false, false, checkProtected, state); 3368 } 3369 getFileAsString4(String name, int nBytesMax, boolean doSpecialLoad, boolean allowBinary, boolean checkProtected, String state)3370 public String getFileAsString4(String name, int nBytesMax, 3371 boolean doSpecialLoad, boolean allowBinary, 3372 boolean checkProtected, String state) { 3373 if (name == null) 3374 return getCurrentFileAsString(state); 3375 String[] data = new String[] { name, null }; 3376 // ignore error completely 3377 fm.getFileDataAsString(data, nBytesMax, doSpecialLoad, allowBinary, 3378 checkProtected); 3379 return data[1]; 3380 } 3381 getAsciiFileOrNull(String name)3382 public String getAsciiFileOrNull(String name) { 3383 String[] data = new String[] { name, null }; 3384 return (fm.getFileDataAsString(data, -1, false, false, false) ? data[1] 3385 : null); 3386 } 3387 3388 // /////////////////////////////////////////////////////////////// 3389 // delegated to ModelManager 3390 // /////////////////////////////////////////////////////////////// 3391 autoCalculate(int tokProperty, String dataType)3392 public void autoCalculate(int tokProperty, String dataType) { 3393 switch (tokProperty) { 3394 case T.surfacedistance: 3395 ms.getSurfaceDistanceMax(); 3396 break; 3397 case T.straightness: 3398 ms.calculateStraightnessAll(); 3399 break; 3400 case T.dssr: 3401 ms.calculateDssrProperty(dataType); 3402 } 3403 } 3404 3405 // This was just the sum of the atomic volumes, not considering overlap 3406 // It was never documented. 3407 // Removed in Jmol 13.0.RC4 3408 3409 // public float getVolume(BitSet bs, String type) { 3410 // // Eval.calculate(), math function volume({atomExpression},"type") 3411 // if (bs == null) 3412 // bs = getSelectionSet(); 3413 // EnumVdw vType = EnumVdw.getVdwType(type); 3414 // if (vType == null) 3415 // vType = EnumVdw.AUTO; 3416 // return modelSet.calculateVolume(bs, vType); 3417 // } 3418 calculateStraightness()3419 public void calculateStraightness() { 3420 ms.haveStraightness = false; 3421 ms.calculateStraightnessAll(); 3422 } 3423 calculateSurface(BS bsSelected, float envelopeRadius)3424 public P3[] calculateSurface(BS bsSelected, float envelopeRadius) { 3425 if (bsSelected == null) 3426 bsSelected = bsA(); 3427 if (envelopeRadius == Float.MAX_VALUE || envelopeRadius == -1) 3428 ms.addStateScript( 3429 "calculate surfaceDistance " 3430 + (envelopeRadius == Float.MAX_VALUE ? "FROM" : "WITHIN"), 3431 null, bsSelected, null, "", false, true); 3432 return ms.calculateSurface(bsSelected, envelopeRadius); 3433 } 3434 getStructureList()3435 public Map<STR, float[]> getStructureList() { 3436 return g.getStructureList(); 3437 } 3438 setStructureList(float[] list, STR type)3439 public void setStructureList(float[] list, STR type) { 3440 // none, turn, sheet, helix 3441 g.setStructureList(list, type); 3442 ms.setStructureList(getStructureList()); 3443 } 3444 3445 /** 3446 * 3447 * @param bsAtoms 3448 * @param asDSSP 3449 * @param setStructure 3450 * to actually change structures 3451 * @param version 3452 * @return structure string from DSSP 3453 */ calculateStructures(BS bsAtoms, boolean asDSSP, boolean setStructure, int version)3454 public String calculateStructures(BS bsAtoms, boolean asDSSP, 3455 boolean setStructure, int version) { 3456 // Eval 3457 if (bsAtoms == null) 3458 bsAtoms = bsA(); 3459 return ms.calculateStructures(bsAtoms, asDSSP, !am.animationOn, 3460 g.dsspCalcHydrogen, setStructure, version); 3461 } 3462 3463 private JmolAnnotationParser annotationParser, dssrParser; 3464 getAnnotationParser(boolean isDSSR)3465 public JmolAnnotationParser getAnnotationParser(boolean isDSSR) { 3466 return (isDSSR 3467 ? (dssrParser == null 3468 ? (dssrParser = (JmolAnnotationParser) Interface 3469 .getOption("dssx.DSSR1", this, "script")) 3470 : dssrParser) 3471 : (annotationParser == null 3472 ? (annotationParser = (JmolAnnotationParser) Interface 3473 .getOption("dssx.AnnotationParser", this, "script")) 3474 : annotationParser)); 3475 } 3476 3477 @Override getSelectedAtomIterator(BS bsSelected, boolean isGreaterOnly, boolean modelZeroBased, boolean isMultiModel)3478 public AtomIndexIterator getSelectedAtomIterator(BS bsSelected, 3479 boolean isGreaterOnly, 3480 boolean modelZeroBased, 3481 boolean isMultiModel) { 3482 return ms.getSelectedAtomIterator(bsSelected, isGreaterOnly, modelZeroBased, 3483 false, isMultiModel); 3484 } 3485 3486 @Override setIteratorForAtom(AtomIndexIterator iterator, int atomIndex, float distance)3487 public void setIteratorForAtom(AtomIndexIterator iterator, int atomIndex, 3488 float distance) { 3489 ms.setIteratorForAtom(iterator, -1, atomIndex, distance, null); 3490 } 3491 3492 @Override setIteratorForPoint(AtomIndexIterator iterator, int modelIndex, T3 pt, float distance)3493 public void setIteratorForPoint(AtomIndexIterator iterator, int modelIndex, 3494 T3 pt, float distance) { 3495 ms.setIteratorForPoint(iterator, modelIndex, pt, distance); 3496 } 3497 3498 @Override fillAtomData(AtomData atomData, int mode)3499 public void fillAtomData(AtomData atomData, int mode) { 3500 atomData.programInfo = "Jmol Version " + getJmolVersion(); 3501 atomData.fileName = fm.getFileName(); 3502 ms.fillAtomData(atomData, mode); 3503 } 3504 addStateScript(String script, boolean addFrameNumber, boolean postDefinitions)3505 public StateScript addStateScript(String script, boolean addFrameNumber, 3506 boolean postDefinitions) { 3507 // calculate 3508 // configuration 3509 // plot 3510 // rebond 3511 // setPdbConectBonding 3512 return ms.addStateScript(script, null, null, null, null, addFrameNumber, 3513 postDefinitions); 3514 } 3515 3516 private Minimizer minimizer; 3517 private SmilesMatcherInterface smilesMatcher; 3518 getMinimizer(boolean createNew)3519 public Minimizer getMinimizer(boolean createNew) { 3520 return (minimizer == null && createNew 3521 ? (minimizer = (Minimizer) Interface 3522 .getInterface("org.jmol.minimize.Minimizer", this, "script")) 3523 .setProperty("vwr", this) 3524 : minimizer); 3525 } 3526 getSmilesMatcher()3527 public SmilesMatcherInterface getSmilesMatcher() { 3528 return (smilesMatcher == null 3529 ? (smilesMatcher = (SmilesMatcherInterface) Interface 3530 .getInterface("org.jmol.smiles.SmilesMatcher", this, "script")) 3531 : smilesMatcher); 3532 } 3533 clearModelDependentObjects()3534 public void clearModelDependentObjects() { 3535 setFrameOffsets(null, false); 3536 stopMinimization(); 3537 minimizer = null; 3538 smilesMatcher = null; 3539 } 3540 zap(boolean notify, boolean resetUndo, boolean zapModelKit)3541 public void zap(boolean notify, boolean resetUndo, boolean zapModelKit) { 3542 3543 clearThreads(); 3544 if (mm.modelSet == null) { 3545 mm.zap(); 3546 3547 } else { 3548 3549 //setBooleanProperty("appendNew", true); 3550 ligandModelSet = null; 3551 clearModelDependentObjects(); 3552 fm.clear(); 3553 clearRepaintManager(-1); 3554 am.clear(); 3555 tm.clear(); 3556 slm.clear(); 3557 clearAllMeasurements(); 3558 clearMinimization(); 3559 gdata.clear(); 3560 mm.zap(); 3561 if (scm != null) 3562 scm.clear(false); 3563 if (nmrCalculation != null) 3564 getNMRCalculation().setChemicalShiftReference(null, 0); 3565 3566 if (haveDisplay) { 3567 mouse.clear(); 3568 clearTimeouts(); 3569 acm.clear(); 3570 } 3571 stm.clear(g); 3572 tempArray.clear(); 3573 chainMap.clear(); 3574 chainList.clear(); 3575 chainCaseSpecified = false; 3576 //cm.clear(); 3577 definedAtomSets.clear(); 3578 lastData = null; 3579 if (dm != null) 3580 dm.clear(); 3581 setBooleanProperty("legacyjavafloat", false); 3582 if (resetUndo) { 3583 if (zapModelKit) 3584 g.removeParam("_pngjFile"); 3585 if (zapModelKit && g.modelKitMode) { 3586 loadDefaultModelKitModel(null); 3587 } 3588 undoClear(); 3589 } 3590 System.gc(); 3591 } 3592 initializeModel(false); 3593 if (notify) { 3594 setFileLoadStatus(FIL.ZAPPED, null, 3595 (resetUndo ? "resetUndo" : getZapName()), null, null, null); 3596 } 3597 if (Logger.debugging) 3598 Logger.checkMemory(); 3599 } 3600 loadDefaultModelKitModel(Map<String, Object> htParams)3601 private void loadDefaultModelKitModel(Map<String, Object> htParams) { 3602 openStringInlineParamsAppend(getModelkit(false).getDefaultModel(), htParams, true); 3603 setRotationRadius(5.0f, true); 3604 setStringProperty("picking", "assignAtom_C"); 3605 setStringProperty("picking", "assignBond_p"); 3606 } 3607 zapMsg(String msg)3608 private void zapMsg(String msg) { 3609 zap(true, true, false); 3610 echoMessage(msg); 3611 } 3612 echoMessage(String msg)3613 void echoMessage(String msg) { 3614 int iShape = JC.SHAPE_ECHO; 3615 shm.loadShape(iShape); 3616 setShapeProperty(iShape, "font", getFont3D("SansSerif", "Plain", 20)); 3617 setShapeProperty(iShape, "target", "error"); 3618 setShapeProperty(iShape, "text", msg); 3619 } 3620 initializeModel(boolean isAppend)3621 private void initializeModel(boolean isAppend) { 3622 clearThreads(); 3623 if (isAppend) { 3624 am.initializePointers(1); 3625 return; 3626 } 3627 reset(true); 3628 selectAll(); 3629 3630 if (modelkit != null) 3631 modelkit.initializeForModel(); 3632 movingSelected = false; 3633 slm.noneSelected = Boolean.FALSE; 3634 setHoverEnabled(true); 3635 3636 setSelectionHalosEnabled(false); 3637 tm.setCenter(); 3638 3639 am.initializePointers(1); 3640 setBooleanProperty("multipleBondBananas", false); 3641 if (!ms.getMSInfoB("isPyMOL")) { 3642 clearAtomSets(); 3643 setCurrentModelIndex(0); 3644 } 3645 setBackgroundModelIndex(-1); 3646 setFrankOn(getShowFrank()); 3647 startHoverWatcher(true); 3648 3649 setTainted(true); 3650 finalizeTransformParameters(); 3651 } 3652 startHoverWatcher(boolean tf)3653 public void startHoverWatcher(boolean tf) { 3654 if (tf && inMotion || !haveDisplay 3655 || tf && (!hoverEnabled && !sm.haveHoverCallback() || am.animationOn)) 3656 return; 3657 acm.startHoverWatcher(tf); 3658 } 3659 3660 @Override getModelSetPathName()3661 public String getModelSetPathName() { 3662 return mm.modelSetPathName; 3663 } 3664 3665 @Override getModelSetFileName()3666 public String getModelSetFileName() { 3667 return (mm.fileName == null ? getZapName() : mm.fileName); 3668 } 3669 getUnitCellInfoText()3670 public String getUnitCellInfoText() { 3671 SymmetryInterface c = getCurrentUnitCell(); 3672 return (c == null ? "not applicable" : c.getUnitCellInfo()); 3673 } 3674 getUnitCellInfo(int infoType)3675 public float getUnitCellInfo(int infoType) { 3676 SymmetryInterface symmetry = getCurrentUnitCell(); 3677 return (symmetry == null ? Float.NaN 3678 : symmetry.getUnitCellInfoType(infoType)); 3679 } 3680 3681 /** 3682 * 3683 * convert string abc;offset or M3 or M4 to origin and three vectors -- a, b, 3684 * c. The string can be preceded by ! for "reverse of". For example, 3685 * "!a-b,-5a-5b,-c;7/8,0,1/8" offset is optional, but it still needs a 3686 * semicolon: "a/2,b/2,c;" 3687 * @param iModel 3688 * 3689 * @param def 3690 * a string or an M3 or M4 3691 * @return vectors [origin a b c] 3692 */ getV0abc(int iModel, Object def)3693 public T3[] getV0abc(int iModel, Object def) { 3694 SymmetryInterface uc = (iModel < 0 ? getCurrentUnitCell() : getUnitCell(iModel)); 3695 return (uc == null ? null : uc.getV0abc(def)); 3696 } 3697 getCurrentUnitCell()3698 public SymmetryInterface getCurrentUnitCell() { 3699 int iAtom = am.getUnitCellAtomIndex(); 3700 if (iAtom >= 0) 3701 return ms.getUnitCellForAtom(iAtom); 3702 return getUnitCell(am.cmi); 3703 } 3704 getUnitCell(int m)3705 private SymmetryInterface getUnitCell(int m) { 3706 if (m >= 0) 3707 return ms.getUnitCell(m); 3708 BS models = getVisibleFramesBitSet(); 3709 SymmetryInterface ucLast = null; 3710 for (int i = models.nextSetBit(0); i >= 0; i = models.nextSetBit(i + 1)) { 3711 SymmetryInterface uc = ms.getUnitCell(i); 3712 if (uc == null) 3713 continue; 3714 if (ucLast == null) { 3715 ucLast = uc; 3716 continue; 3717 } 3718 if (!ucLast.unitCellEquals(uc)) 3719 return null; 3720 } 3721 return ucLast; 3722 } 3723 3724 getPolymerPointsAndVectors(BS bs, Lst<P3[]> vList)3725 public void getPolymerPointsAndVectors(BS bs, Lst<P3[]> vList) { 3726 ms.getPolymerPointsAndVectors(bs, vList, g.traceAlpha, g.sheetSmoothing); 3727 } 3728 getHybridizationAndAxes(int atomIndex, V3 z, V3 x, String lcaoType)3729 public String getHybridizationAndAxes(int atomIndex, V3 z, V3 x, 3730 String lcaoType) { 3731 return ms.getHybridizationAndAxes(atomIndex, 0, z, x, lcaoType, true, true, 3732 false); 3733 } 3734 getAllAtoms()3735 public BS getAllAtoms() { 3736 return getModelUndeletedAtomsBitSet(-1); 3737 } 3738 getFrameAtoms()3739 public BS getFrameAtoms() { 3740 return getModelUndeletedAtomsBitSetBs(getVisibleFramesBitSet()); 3741 } 3742 3743 @Override getVisibleFramesBitSet()3744 public BS getVisibleFramesBitSet() { 3745 BS bs = BSUtil.copy(am.bsVisibleModels); 3746 if (ms.trajectory != null) 3747 ms.trajectory.selectDisplayed(bs); 3748 return bs; 3749 3750 } 3751 getModelUndeletedAtomsBitSet(int modelIndex)3752 public BS getModelUndeletedAtomsBitSet(int modelIndex) { 3753 return slm.excludeAtoms( 3754 ms.getModelAtomBitSetIncludingDeleted(modelIndex, true), false); 3755 } 3756 getModelUndeletedAtomsBitSetBs(BS bsModels)3757 public BS getModelUndeletedAtomsBitSetBs(BS bsModels) { 3758 return slm.excludeAtoms(ms.getModelAtomBitSetIncludingDeletedBs(bsModels), 3759 false); 3760 } 3761 3762 @Override getBoundBoxCenter()3763 public P3 getBoundBoxCenter() { 3764 return ms.getBoundBoxCenter(am.cmi); 3765 } 3766 calcBoundBoxDimensions(BS bs, float scale)3767 public void calcBoundBoxDimensions(BS bs, float scale) { 3768 ms.calcBoundBoxDimensions(bs, scale); 3769 axesAreTainted = true; 3770 } 3771 3772 @Override getBoundBoxCornerVector()3773 public V3 getBoundBoxCornerVector() { 3774 return ms.getBoundBoxCornerVector(); 3775 } 3776 3777 @Override getModelSetProperties()3778 public Properties getModelSetProperties() { 3779 return ms.modelSetProperties; 3780 } 3781 3782 @Override getModelProperties(int modelIndex)3783 public Properties getModelProperties(int modelIndex) { 3784 return ms.am[modelIndex].properties; 3785 } 3786 getModelForAtomIndex(int iatom)3787 public Model getModelForAtomIndex(int iatom) { 3788 return ms.am[ms.at[iatom].mi]; 3789 } 3790 3791 @Override getModelSetAuxiliaryInfo()3792 public Map<String, Object> getModelSetAuxiliaryInfo() { 3793 return ms.getAuxiliaryInfo(null); 3794 } 3795 3796 @Override getModelNumber(int modelIndex)3797 public int getModelNumber(int modelIndex) { 3798 return (modelIndex < 0 ? modelIndex : ms.getModelNumber(modelIndex)); 3799 } 3800 getModelFileNumber(int modelIndex)3801 public int getModelFileNumber(int modelIndex) { 3802 return (modelIndex < 0 ? 0 : ms.modelFileNumbers[modelIndex]); 3803 } 3804 3805 @Override getModelNumberDotted(int modelIndex)3806 public String getModelNumberDotted(int modelIndex) { 3807 // must not return "all" for -1, because this could be within a frame RANGE 3808 return modelIndex < 0 ? "0" : ms.getModelNumberDotted(modelIndex); 3809 } 3810 3811 @Override getModelName(int modelIndex)3812 public String getModelName(int modelIndex) { 3813 return ms.getModelName(modelIndex); 3814 } 3815 modelHasVibrationVectors(int modelIndex)3816 public boolean modelHasVibrationVectors(int modelIndex) { 3817 return (ms.getLastVibrationVector(modelIndex, T.vibration) >= 0); 3818 } 3819 getBondsForSelectedAtoms(BS bsAtoms)3820 public BS getBondsForSelectedAtoms(BS bsAtoms) { 3821 // eval 3822 return ms.getBondsForSelectedAtoms(bsAtoms, 3823 g.bondModeOr || BSUtil.cardinalityOf(bsAtoms) == 1); 3824 } 3825 frankClicked(int x, int y)3826 public boolean frankClicked(int x, int y) { 3827 // bottom right Jmol logo 3828 return !g.disablePopupMenu && getShowFrank() && shm.checkFrankclicked(x, y); 3829 } 3830 frankClickedModelKit(int x, int y)3831 public boolean frankClickedModelKit(int x, int y) { 3832 // top left indicator 3833 return !g.disablePopupMenu && g.modelKitMode && x >= 0 && y >= 0 && x < 40 3834 && y < 26*4; // See FrankRenderer 3835 } 3836 3837 @Override findNearestAtomIndex(int x, int y)3838 public int findNearestAtomIndex(int x, int y) { 3839 return findNearestAtomIndexMovable(x, y, false); 3840 } 3841 findNearestAtomIndexMovable(int x, int y, boolean mustBeMovable)3842 public int findNearestAtomIndexMovable(int x, int y, boolean mustBeMovable) { 3843 return (!g.atomPicking ? -1 3844 : ms.findNearestAtomIndex(x, y, 3845 mustBeMovable ? slm.getMotionFixedAtoms() : null, 3846 g.minPixelSelRadius)); 3847 } 3848 3849 /** 3850 * absolute or relative to origin of UNITCELL {x y z} 3851 * 3852 * @param pt 3853 * @param ignoreOffset 3854 * TODO 3855 */ toCartesian(T3 pt, boolean ignoreOffset)3856 public void toCartesian(T3 pt, boolean ignoreOffset) { 3857 SymmetryInterface unitCell = getCurrentUnitCell(); 3858 if (unitCell != null) { 3859 unitCell.toCartesian(pt, ignoreOffset); 3860 if (!g.legacyJavaFloat) 3861 PT.fixPtFloats(pt, PT.CARTESIAN_PRECISION); 3862 } 3863 } 3864 3865 /** 3866 * 3867 * @param pt 3868 * @param ignoreOffset 3869 * set true for relative to {0 0 0}; otherwise relative to origin of 3870 * UNITCELL {x y z} 3871 */ toFractional(T3 pt, boolean ignoreOffset)3872 public void toFractional(T3 pt, boolean ignoreOffset) { 3873 SymmetryInterface unitCell = getCurrentUnitCell(); 3874 if (unitCell != null) { 3875 unitCell.toFractional(pt, ignoreOffset); 3876 if (!g.legacyJavaFloat) 3877 PT.fixPtFloats(pt, PT.FRACTIONAL_PRECISION); 3878 } 3879 3880 } 3881 3882 /** 3883 * relative to origin without regard to UNITCELL {x y z} 3884 * 3885 * @param pt 3886 * @param offset 3887 */ toUnitCell(P3 pt, P3 offset)3888 public void toUnitCell(P3 pt, P3 offset) { 3889 SymmetryInterface unitCell = getCurrentUnitCell(); 3890 if (unitCell != null) 3891 unitCell.toUnitCell(pt, offset); 3892 } 3893 setCurrentCage(String isosurfaceId)3894 public void setCurrentCage(String isosurfaceId) { 3895 Object[] data = new Object[] { isosurfaceId, null }; 3896 shm.getShapePropertyData(JC.SHAPE_ISOSURFACE, "unitCell", data); 3897 ms.setModelCage(am.cmi, (SymmetryInterface) data[1]); 3898 } 3899 addUnitCellOffset(P3 pt)3900 public void addUnitCellOffset(P3 pt) { 3901 SymmetryInterface unitCell = getCurrentUnitCell(); 3902 if (unitCell == null) 3903 return; 3904 pt.add(unitCell.getCartesianOffset()); 3905 } 3906 setAtomData(int type, String name, String coordinateData, boolean isDefault)3907 public void setAtomData(int type, String name, String coordinateData, 3908 boolean isDefault) { 3909 // DATA "xxxx" 3910 // atom coordinates may be moved here 3911 // but this is not included as an atomMovedCallback 3912 ms.setAtomData(type, name, coordinateData, isDefault); 3913 if (type == AtomCollection.TAINT_COORD) 3914 checkCoordinatesChanged(); 3915 refreshMeasures(true); 3916 } 3917 3918 @Override setCenterSelected()3919 public void setCenterSelected() { 3920 // depricated 3921 setCenterBitSet(bsA(), true); 3922 } 3923 setApplySymmetryToBonds(boolean TF)3924 void setApplySymmetryToBonds(boolean TF) { 3925 g.applySymmetryToBonds = TF; 3926 } 3927 3928 @Override setBondTolerance(float bondTolerance)3929 public void setBondTolerance(float bondTolerance) { 3930 g.setF("bondTolerance", bondTolerance); 3931 g.bondTolerance = bondTolerance; 3932 } 3933 3934 @Override setMinBondDistance(float minBondDistance)3935 public void setMinBondDistance(float minBondDistance) { 3936 // PreferencesDialog 3937 g.setF("minBondDistance", minBondDistance); 3938 g.minBondDistance = minBondDistance; 3939 } 3940 getAtomsNearPt(float distance, P3 coord)3941 public BS getAtomsNearPt(float distance, P3 coord) { 3942 BS bs = new BS(); 3943 ms.getAtomsWithin(distance, coord, bs, -1); 3944 return bs; 3945 } 3946 3947 /** 3948 * given a set of atoms, a subset of atoms to test, two atoms that start the 3949 * branch, and whether or not to allow the branch to cycle back on 3950 * itself,deliver the set of atoms constituting this branch. 3951 * 3952 * @param atomIndex 3953 * @param atomIndexNot 3954 * @param allowCyclic 3955 * @return bitset for this branch 3956 */ getBranchBitSet(int atomIndex, int atomIndexNot, boolean allowCyclic)3957 public BS getBranchBitSet(int atomIndex, int atomIndexNot, 3958 boolean allowCyclic) { 3959 if (atomIndex < 0 || atomIndex >= ms.ac) 3960 return new BS(); 3961 return JmolMolecule.getBranchBitSet(ms.at, atomIndex, 3962 getModelUndeletedAtomsBitSet(ms.at[atomIndex].mi), null, atomIndexNot, 3963 allowCyclic, true); 3964 } 3965 3966 @Override getElementsPresentBitSet(int modelIndex)3967 public BS getElementsPresentBitSet(int modelIndex) { 3968 return ms.getElementsPresentBitSet(modelIndex); 3969 } 3970 getFileHeader()3971 String getFileHeader() { 3972 return ms.getFileHeader(am.cmi); 3973 } 3974 getFileData()3975 Object getFileData() { 3976 return ms.getFileData(am.cmi); 3977 } 3978 getCifData(int modelIndex)3979 public Map<String, Object> getCifData(int modelIndex) { 3980 return readCifData(ms.getModelFileName(modelIndex), 3981 ms.getModelFileType(modelIndex).toUpperCase()); 3982 } 3983 readCifData(String fileName, String type)3984 public Map<String, Object> readCifData(String fileName, String type) { 3985 String fname = (fileName == null ? ms.getModelFileName(am.cmi) : fileName); 3986 if (type == null && fname != null 3987 && fname.toUpperCase().indexOf("BCIF") >= 0) { 3988 BufferedInputStream is = fm.getBufferedInputStream(fname); 3989 try { 3990 return ((javajs.util.MessagePackReader) Interface 3991 .getInterface("javajs.util.MessagePackReader", this, "script")) 3992 .getMapForStream(is); 3993 } catch (Exception e) { 3994 e.printStackTrace(); 3995 return new Hashtable<String, Object>(); 3996 } 3997 } 3998 String data = (fileName == null || fileName.length() == 0 3999 ? getCurrentFileAsString("script") 4000 : getFileAsString3(fileName, false, null)); 4001 if (data == null || data.length() < 2) 4002 return null; 4003 BufferedReader rdr = Rdr.getBR(data); 4004 if (type == null) 4005 type = getModelAdapter().getFileTypeName(rdr); 4006 return (type == null ? null : readCifData(null, rdr, type)); 4007 4008 } 4009 4010 @Override readCifData(String fileName, Object rdrOrStringData, String type)4011 public Map<String, Object> readCifData(String fileName, 4012 Object rdrOrStringData, String type) { 4013 if (rdrOrStringData == null) 4014 rdrOrStringData = getFileAsString(fileName); 4015 BufferedReader rdr = (rdrOrStringData instanceof BufferedReader 4016 ? (BufferedReader) rdrOrStringData 4017 : Rdr.getBR((String) rdrOrStringData)); 4018 return Rdr.readCifData((GenericCifDataParser) Interface.getInterface( 4019 ("Cif2".equals(type) ? "org.jmol.adapter.readers.cif.Cif2DataParser" 4020 : "javajs.util.CifDataParser"), 4021 this, "script"), rdr); 4022 } 4023 4024 JmolStateCreator jsc; 4025 getStateCreator()4026 public JmolStateCreator getStateCreator() { 4027 if (jsc == null) 4028 (jsc = (JmolStateCreator) Interface 4029 .getInterface("org.jmol.viewer.StateCreator", this, "script")) 4030 .setViewer(this); 4031 return jsc; 4032 } 4033 getWrappedStateScript()4034 public String getWrappedStateScript() { 4035 return (String) getOutputManager().getWrappedState(null, null, null, null); 4036 } 4037 4038 @Override getStateInfo()4039 public String getStateInfo() { 4040 return getStateInfo3(null, 0, 0); 4041 } 4042 getStateInfo3(String type, int width, int height)4043 public String getStateInfo3(String type, int width, int height) { 4044 return (g.preserveState 4045 ? getStateCreator().getStateScript(type, width, height) 4046 : ""); 4047 } 4048 getStructureState()4049 public String getStructureState() { 4050 return getStateCreator().getModelState(null, false, true); 4051 } 4052 getCoordinateState(BS bsSelected)4053 public String getCoordinateState(BS bsSelected) { 4054 return getStateCreator().getAtomicPropertyState(AtomCollection.TAINT_COORD, 4055 bsSelected); 4056 } 4057 setCurrentColorRange(String label)4058 public void setCurrentColorRange(String label) { 4059 float[] data = (float[]) getDataObj(label, null, 4060 JmolDataManager.DATA_TYPE_AF); 4061 BS bs = (data == null ? null 4062 : (BS) ((Object[]) getDataObj(label, null, 4063 JmolDataManager.DATA_TYPE_UNKNOWN))[2]); 4064 if (bs != null && g.rangeSelected) 4065 bs.and(bsA()); 4066 cm.setPropertyColorRangeData(data, bs); 4067 } 4068 4069 private Object[] lastData; 4070 4071 /** 4072 * A general-purpose data storage method. Note that matchFieldCount and 4073 * dataFieldCount should both be positive or both be negative. 4074 * 4075 * @param key 4076 * 4077 * a simple key name for the data, starting with "property_" if 4078 * user-defined 4079 * 4080 * @param data 4081 * 4082 * data[0] -- label 4083 * 4084 * data[1] -- string or float[] or float[][] or float[][][] 4085 * 4086 * data[2] -- selection bitset or int[] atomMap when field > 0 4087 * 4088 * data[3] -- arrayDepth 4089 * 0(String),1(float[]),2(float[][]),3(float[][][]) or -1 to indidate 4090 * that it is set by data type 4091 * 4092 * data[4] -- Boolean.TRUE == saveInState 4093 * 4094 * @param dataType 4095 * 4096 * see JmolDataManager interface 4097 * 4098 * @param matchField 4099 * 4100 * if positive, data must match atomNo in this column 4101 * 4102 * if 0, no match column 4103 * 4104 * @param matchFieldColumnCount 4105 * if positive, this number of characters in match column if 0, 4106 * reference is to tokens, not characters 4107 * 4108 * @param dataField 4109 * 4110 * if positive, column containing the data 4111 * 4112 * if 0, values are a simple list; clear the data 4113 * 4114 * if Integer.MAX_VALUE, values are a simple list; don't clear the data 4115 * 4116 * if Integer.MIN_VALUE, have one SINGLE data value for all selected 4117 * atoms 4118 * 4119 * @param dataFieldColumnCount 4120 * 4121 * if positive, this number of characters in data column 4122 * 4123 * if 0, reference is to tokens, not characters 4124 */ setData(String key, Object[] data, int dataType, int matchField, int matchFieldColumnCount, int dataField, int dataFieldColumnCount)4125 public void setData(String key, Object[] data, int dataType, int matchField, 4126 int matchFieldColumnCount, int dataField, 4127 int dataFieldColumnCount) { 4128 getDataManager().setData(key, lastData = data, dataType, ms.ac, matchField, 4129 matchFieldColumnCount, dataField, dataFieldColumnCount); 4130 } 4131 4132 /** 4133 * Retrieve a data object 4134 * 4135 * @param key 4136 * 4137 * @param bsSelected 4138 * 4139 * selected atoms; for DATA_AF only 4140 * 4141 * @param dataType 4142 * 4143 * see JmolDataManager interface 4144 * 4145 * @return data object 4146 * 4147 * data[0] -- label (same as key) 4148 * 4149 * data[1] -- string or float[] or float[][] or float[][][] 4150 * 4151 * data[2] -- selection bitset or int[] atomMap when field > 0 4152 * 4153 * data[3] -- arrayDepth 4154 * 0(String),1(float[]),2(float[][]),3(float[][][]) or -1 to indicate 4155 * that it is set by data type 4156 * 4157 * data[4] -- Boolean.TRUE == saveInState 4158 */ getDataObj(String key, BS bsSelected, int dataType)4159 public Object getDataObj(String key, BS bsSelected, int dataType) { 4160 return (key == null && dataType == JmolDataManager.DATA_TYPE_LAST ? lastData 4161 : getDataManager().getData(key, bsSelected, dataType)); 4162 } 4163 4164 // public float getDataFloatAt(String label, int atomIndex) { 4165 // return getDataManager().getDataFloatAt(label, atomIndex); 4166 // } 4167 4168 // boolean autoLoadOrientation() { 4169 // return true;//global.autoLoadOrientation; 12.0.RC10 4170 // } 4171 autoHbond(BS bsFrom, BS bsTo, boolean onlyIfHaveCalculated)4172 public int autoHbond(BS bsFrom, BS bsTo, boolean onlyIfHaveCalculated) { 4173 if (bsFrom == null) 4174 bsFrom = bsTo = bsA(); 4175 // bsTo null --> use DSSP method further developed 4176 // here to give the "defining" Hbond set only 4177 return ms.autoHbond(bsFrom, bsTo, onlyIfHaveCalculated); 4178 } 4179 4180 /* 4181 * **************************************************************************** 4182 * delegated to MeasurementManager 4183 * ************************************************************************** 4184 */ 4185 getDefaultMeasurementLabel(int nPoints)4186 public String getDefaultMeasurementLabel(int nPoints) { 4187 switch (nPoints) { 4188 case 2: 4189 return g.defaultDistanceLabel; 4190 case 3: 4191 return g.defaultAngleLabel; 4192 default: 4193 return g.defaultTorsionLabel; 4194 } 4195 } 4196 4197 @Override getMeasurementCount()4198 public int getMeasurementCount() { 4199 int count = getShapePropertyAsInt(JC.SHAPE_MEASURES, "count"); 4200 return count <= 0 ? 0 : count; 4201 } 4202 4203 @Override getMeasurementStringValue(int i)4204 public String getMeasurementStringValue(int i) { 4205 return "" + shm.getShapePropertyIndex(JC.SHAPE_MEASURES, "stringValue", i); 4206 } 4207 getMeasurementInfoAsString()4208 public String getMeasurementInfoAsString() { 4209 return (String) getShapeProperty(JC.SHAPE_MEASURES, "infostring"); 4210 } 4211 4212 @Override getMeasurementCountPlusIndices(int i)4213 public int[] getMeasurementCountPlusIndices(int i) { 4214 return (int[]) shm.getShapePropertyIndex(JC.SHAPE_MEASURES, 4215 "countPlusIndices", i); 4216 } 4217 setPendingMeasurement(MeasurementPending mp)4218 void setPendingMeasurement(MeasurementPending mp) { 4219 // from MouseManager 4220 shm.loadShape(JC.SHAPE_MEASURES); 4221 setShapeProperty(JC.SHAPE_MEASURES, "pending", mp); 4222 } 4223 getPendingMeasurement()4224 public MeasurementPending getPendingMeasurement() { 4225 return (MeasurementPending) getShapeProperty(JC.SHAPE_MEASURES, "pending"); 4226 } 4227 clearAllMeasurements()4228 public void clearAllMeasurements() { 4229 // Eval only 4230 setShapeProperty(JC.SHAPE_MEASURES, "clear", null); 4231 } 4232 4233 @Override clearMeasurements()4234 public void clearMeasurements() { 4235 // depricated but in the API -- use "script" directly 4236 // see clearAllMeasurements() 4237 evalString("measures delete"); 4238 } 4239 4240 // /////////////////////////////////////////////////////////////// 4241 // delegated to AnimationManager 4242 // /////////////////////////////////////////////////////////////// 4243 setAnimation(int tok)4244 public void setAnimation(int tok) { 4245 switch (tok) { 4246 case T.playrev: 4247 am.reverseAnimation(); 4248 //$FALL-THROUGH$ 4249 case T.play: 4250 case T.resume: 4251 if (!am.animationOn) 4252 am.resumeAnimation(); 4253 return; 4254 case T.pause: 4255 if (am.animationOn && !am.animationPaused) 4256 am.pauseAnimation(); 4257 return; 4258 case T.next: 4259 am.setAnimationNext(); 4260 return; 4261 case T.prev: 4262 am.setAnimationPrevious(); 4263 return; 4264 case T.first: 4265 case T.rewind: 4266 am.rewindAnimation(); 4267 return; 4268 case T.last: 4269 am.setAnimationLast(); 4270 return; 4271 } 4272 } 4273 4274 @Override setAnimationFps(int fps)4275 public void setAnimationFps(int fps) { 4276 am.setAnimationFps(fps); 4277 } 4278 setAnimationMode(String mode)4279 private void setAnimationMode(String mode) { 4280 if (mode.equalsIgnoreCase("once")) { 4281 am.setAnimationReplayMode(T.once, 0, 0); 4282 } else if (mode.equalsIgnoreCase("loop")) { 4283 am.setAnimationReplayMode(T.loop, 1, 1); 4284 } else if (mode.startsWith("pal")) { 4285 am.setAnimationReplayMode(T.palindrome, 1, 1); 4286 } 4287 } 4288 setAnimationOn(boolean animationOn)4289 public void setAnimationOn(boolean animationOn) { 4290 // Eval 4291 boolean wasAnimating = am.animationOn; 4292 if (animationOn == wasAnimating) 4293 return; 4294 am.setAnimationOn(animationOn); 4295 } 4296 setAnimationRange(int modelIndex1, int modelIndex2)4297 public void setAnimationRange(int modelIndex1, int modelIndex2) { 4298 am.setAnimationRange(modelIndex1, modelIndex2); 4299 } 4300 defineAtomSets(Map<String, Object> info)4301 public void defineAtomSets(Map<String, Object> info) { 4302 definedAtomSets.putAll(info); 4303 } 4304 setAnimDisplay(BS bs)4305 public void setAnimDisplay(BS bs) { 4306 am.setDisplay(bs); 4307 if (!am.animationOn) 4308 am.morph(am.currentMorphModel + 1); 4309 } 4310 setCurrentModelIndex(int modelIndex)4311 public void setCurrentModelIndex(int modelIndex) { 4312 // Eval 4313 // initializeModel 4314 if (modelIndex == Integer.MIN_VALUE) { 4315 // just forcing popup menu update 4316 prevFrame = Integer.MIN_VALUE; 4317 setCurrentModelIndexClear(am.cmi, true); 4318 return; 4319 } 4320 am.setModel(modelIndex, true); 4321 } 4322 getTrajectoryState()4323 public String getTrajectoryState() { 4324 return (ms.trajectory == null ? "" : ms.trajectory.getState()); 4325 } 4326 setFrameOffsets(BS bsAtoms, boolean isFull)4327 public void setFrameOffsets(BS bsAtoms, boolean isFull) { 4328 tm.bsFrameOffsets = null; 4329 if (isFull) 4330 clearModelDependentObjects(); 4331 else 4332 tm.bsFrameOffsets = bsAtoms; 4333 tm.frameOffsets = ms.getFrameOffsets(bsAtoms, isFull); 4334 } 4335 setCurrentModelIndexClear(int modelIndex, boolean clearBackground)4336 public void setCurrentModelIndexClear(int modelIndex, 4337 boolean clearBackground) { 4338 // Eval 4339 // initializeModel 4340 am.setModel(modelIndex, clearBackground); 4341 } 4342 haveFileSet()4343 public boolean haveFileSet() { 4344 return (ms.mc > 1 && getModelNumber(Integer.MAX_VALUE) > 2000000); 4345 } 4346 setBackgroundModelIndex(int modelIndex)4347 public void setBackgroundModelIndex(int modelIndex) { 4348 am.setBackgroundModelIndex(modelIndex); 4349 g.setO("backgroundModel", ms.getModelNumberDotted(modelIndex)); 4350 } 4351 setFrameVariables()4352 void setFrameVariables() { 4353 g.setO("animationMode", T.nameOf(am.animationReplayMode)); 4354 g.setI("animationFps", am.animationFps); 4355 g.setO("_firstFrame", am.getModelSpecial(-1)); 4356 g.setO("_lastFrame", am.getModelSpecial(1)); 4357 g.setF("_animTimeSec", am.getAnimRunTimeSeconds()); 4358 g.setB("_animMovie", am.isMovie); 4359 } 4360 4361 private int motionEventNumber; 4362 private boolean inMotion; 4363 getInMotion(boolean includeAnim)4364 public boolean getInMotion(boolean includeAnim) { 4365 return (inMotion || includeAnim && am.animationOn); 4366 } 4367 4368 @Override getMotionEventNumber()4369 public int getMotionEventNumber() { 4370 return motionEventNumber; 4371 } 4372 4373 @Override setInMotion(boolean inMotion)4374 public void setInMotion(boolean inMotion) { 4375 if (this.inMotion ^ inMotion) { 4376 this.inMotion = inMotion; 4377 resizeImage(0, 0, false, false, true); // for antialiasdisplay 4378 if (inMotion) { 4379 startHoverWatcher(false); 4380 ++motionEventNumber; 4381 } else { 4382 startHoverWatcher(true); 4383 refresh(REFRESH_SYNC_MASK, "vwr setInMotion " + inMotion); 4384 } 4385 } 4386 } 4387 4388 private boolean refreshing = true; 4389 setRefreshing(boolean TF)4390 private void setRefreshing(boolean TF) { 4391 refreshing = TF; 4392 } 4393 getRefreshing()4394 public boolean getRefreshing() { 4395 return refreshing; 4396 } 4397 4398 @Override pushHoldRepaint()4399 public void pushHoldRepaint() { 4400 pushHoldRepaintWhy(null); 4401 } 4402 4403 /** 4404 * 4405 * @param why 4406 */ pushHoldRepaintWhy(String why)4407 public void pushHoldRepaintWhy(String why) { 4408 if (rm != null) 4409 rm.pushHoldRepaint(why); 4410 } 4411 4412 @Override popHoldRepaint(String why)4413 public void popHoldRepaint(String why) { 4414 if (rm != null) { 4415 rm.popHoldRepaint(why.indexOf(JC.REPAINT_IGNORE) < 0, why); 4416 } 4417 } 4418 4419 public final static int REFRESH_REPAINT = 1; 4420 public final static int REFRESH_SYNC = 2; 4421 public final static int REFRESH_SYNC_MASK = REFRESH_REPAINT | REFRESH_SYNC; 4422 public final static int REFRESH_REPAINT_NO_MOTION_ONLY = 6; 4423 public final static int REFRESH_SEND_WEBGL_NEW_ORIENTATION = 7; 4424 4425 /** 4426 * initiate a repaint/update sequence if it has not already been requested. 4427 * invoked whenever any operation causes changes that require new rendering. 4428 * 4429 * The repaint/update sequence will only be invoked if (a) no repaint is 4430 * already pending and (b) there is no hold flag set in repaintManager. 4431 * 4432 * Sequence is as follows: 4433 * 4434 * 1) RepaintManager.refresh() checks flags and then calls Viewer.repaint() 4435 * 4436 * 2) Viewer.repaint() invokes display.repaint(), provided display is not null 4437 * (headless) 4438 * 4439 * 3) The system responds with an invocation of Jmol.update(Graphics g), which 4440 * we are routing through Jmol.paint(Graphics g). 4441 * 4442 * 4) Jmol.update invokes Viewer.setScreenDimensions(size), which makes the 4443 * necessary changes in parameters for any new window size. 4444 * 4445 * 5) Jmol.update invokes Viewer.renderScreenImage(g, size, rectClip) 4446 * 4447 * 6) Viewer.renderScreenImage checks object visibility, invokes render1 to do 4448 * the actual creation of the image pixel map and send it to the screen, and 4449 * then invokes repaintView() 4450 * 4451 * 7) Viewer.repaintView() invokes RepaintManager.repaintDone(), to clear the 4452 * flags and then use notify() to release any threads holding on wait(). 4453 * 4454 * @param mode 4455 * 4456 * REFRESH_REPAINT: ONLY do a repaint -- no syncing 4457 * 4458 * REFRESH_SYNC: mouse motion requiring synchronization -- not going 4459 * through Eval so we bypass Eval and mainline on the other vwr! Also 4460 * called from j2sApplet.js 4461 * 4462 * REFRESH_REPAINT_SYNC_MASK: same as REFRESH_REPAINT, but not WebGL 4463 * 4464 * REFRESH_NO_MOTION_ONLY: refresh only if not in motion 4465 * 4466 * REFRESH_SEND_WEBGL_NEW_ORIENTATION: send WebGL a "new orientation" 4467 * command at the end of a script using html5applet._refresh() 4468 * 4469 * 4470 * @param strWhy 4471 * debugging or for passing mouse command when using REFRESH_SYNC 4472 * 4473 */ 4474 @Override 4475 public void refresh(int mode, String strWhy) { 4476 4477 if (rm == null || !refreshing 4478 || mode == REFRESH_REPAINT_NO_MOTION_ONLY && getInMotion(true) 4479 || !isWebGL && mode == REFRESH_SEND_WEBGL_NEW_ORIENTATION) 4480 return; 4481 if (isWebGL) { 4482 switch (mode) { 4483 case REFRESH_REPAINT: 4484 case REFRESH_SYNC: 4485 case REFRESH_SEND_WEBGL_NEW_ORIENTATION: 4486 tm.finalizeTransformParameters(); 4487 if (html5Applet == null) 4488 return; 4489 html5Applet._refresh(); 4490 if (mode == REFRESH_SEND_WEBGL_NEW_ORIENTATION) 4491 return; 4492 break; 4493 } 4494 } else { 4495 rm.repaintIfReady("refresh " + mode + " " + strWhy); 4496 } 4497 // Q: Why this, since all of these % 3 != 0 4498 if (/*mode % REFRESH_SYNC_MASK != 0 && */ sm.doSync()) 4499 sm.setSync(mode == REFRESH_SYNC ? strWhy : null); 4500 } 4501 4502 public void requestRepaintAndWait(String why) { 4503 // called by moveUpdate from move, moveTo, navigate, 4504 // navTranslate 4505 // called by ScriptEvaluator "refresh" command 4506 // called by AnimationThread run() 4507 // called by TransformationManager move and moveTo 4508 // called by TransformationManager11 navigate, navigateTo 4509 if (rm == null) 4510 return; 4511 if (!haveDisplay) { 4512 setModelVisibility(); 4513 shm.finalizeAtoms(null, true); 4514 return; 4515 } 4516 rm.requestRepaintAndWait(why); 4517 setSync(); 4518 } 4519 4520 public void clearShapeRenderers() { 4521 clearRepaintManager(-1); 4522 } 4523 4524 public boolean isRepaintPending() { 4525 return (rm == null ? false : rm.isRepaintPending()); 4526 } 4527 4528 @Override 4529 public void notifyViewerRepaintDone() { 4530 if (rm != null) 4531 rm.repaintDone(); 4532 am.repaintDone(); 4533 } 4534 4535 private boolean axesAreTainted = false; 4536 4537 public boolean areAxesTainted() { 4538 boolean TF = axesAreTainted; 4539 axesAreTainted = false; 4540 return TF; 4541 } 4542 4543 @Override 4544 public String generateOutputForExport(Map<String, Object> params) { 4545 return (noGraphicsAllowed || rm == null ? null 4546 : getOutputManager().getOutputFromExport(params)); 4547 } 4548 4549 private void clearRepaintManager(int iShape) { 4550 if (rm != null) 4551 rm.clear(iShape); 4552 } 4553 4554 /** 4555 * JmolViewer interface uses this, but that is all 4556 */ 4557 @Override 4558 public void renderScreenImage(Object g, int width, int height) { 4559 renderScreenImageStereo(g, false, width, height); 4560 } 4561 4562 public void renderScreenImageStereo(Object gLeft, boolean checkStereoSlave, 4563 int width, int height) { 4564 // from paint/update event 4565 // gRight is for second stereo applet 4566 // when this is the stereoSlave, no rendering occurs through this applet 4567 // directly, only from the other applet. 4568 // this is for relatively specialized geoWall-type installations 4569 4570 // Jmol repaint/update system for the application: 4571 // 4572 // threads invoke vwr.refresh() 4573 // 4574 // --> repaintManager.refresh() 4575 // --> vwr.repaint() 4576 // --> display.repaint() 4577 // --> OS event queue calls Applet.paint() 4578 // --> vwr.renderScreenImage() 4579 // --> vwr.notifyViewerRepaintDone() 4580 // --> repaintManager.repaintDone() 4581 // --> which sets repaintPending false and does notify(); 4582 4583 if (updateWindow(width, height)) { 4584 if (!checkStereoSlave || gRight == null) { 4585 getScreenImageBuffer(gLeft, false); 4586 } else { 4587 drawImage(gRight, getImage(true, false), 0, 0, tm.stereoDoubleDTI); 4588 drawImage(gLeft, getImage(false, false), 0, 0, tm.stereoDoubleDTI); 4589 } 4590 } 4591 if (captureParams != null 4592 && Boolean.FALSE != captureParams.get("captureEnabled")) { 4593 captureParams.remove("imagePixels"); 4594 //showString(transformManager.matrixRotate.toString(), false); 4595 long t = ((Long) captureParams.get("endTime")).longValue(); 4596 if (t > 0 && System.currentTimeMillis() + 50 > t) 4597 captureParams.put("captureMode", "end"); 4598 processWriteOrCapture(captureParams); 4599 } 4600 notifyViewerRepaintDone(); 4601 } 4602 4603 public Map<String, Object> captureParams; 4604 private Map<String, Object> jsParams; 4605 4606 /** 4607 * for JavaScript only 4608 * 4609 */ updateJS()4610 public void updateJS() { 4611 if (isWebGL) { 4612 if (jsParams == null) { 4613 jsParams = new Hashtable<String, Object>(); 4614 jsParams.put("type", "JS"); 4615 } 4616 if (updateWindow(0, 0)) 4617 render(); 4618 notifyViewerRepaintDone(); 4619 } else { 4620 if (isStereoSlave) 4621 return; 4622 // getGraphics returns a canvas context2d 4623 renderScreenImageStereo(apiPlatform.getGraphics(null), true, 0, 0); 4624 } 4625 } 4626 4627 /** 4628 * File has been loaded or model has been changed or atom picked. This is a 4629 * call to Jmol.View for view sets (new in Jmol 14.1.8) 4630 * 4631 * @param imodel 4632 * @param iatom 4633 * 4634 */ updateJSView(int imodel, int iatom)4635 private void updateJSView(int imodel, int iatom) { 4636 if (html5Applet == null) 4637 return; 4638 @SuppressWarnings("unused") 4639 JSmolAppletObject applet = this.html5Applet; 4640 boolean doViewPick = true; 4641 /** 4642 * @j2sNative 4643 * 4644 * doViewPick = (applet != null && applet._viewSet != null); 4645 * 4646 */ 4647 { 4648 } 4649 if (doViewPick) 4650 html5Applet._atomPickedCallback(imodel, iatom); 4651 } 4652 4653 // /////////////////////////////////////////////////////////////// 4654 // routines for script support 4655 // /////////////////////////////////////////////////////////////// 4656 4657 @Override evalFile(String strFilename)4658 public String evalFile(String strFilename) { 4659 // from JmolApp and test suite only 4660 return (allowScripting && getScriptManager() != null 4661 ? scm.evalFile(strFilename) 4662 : null); 4663 } 4664 getInsertedCommand()4665 public String getInsertedCommand() { 4666 String s = insertedCommand; 4667 insertedCommand = ""; 4668 if (Logger.debugging && s != "") 4669 Logger.debug("inserting: " + s); 4670 return s; 4671 } 4672 4673 @Override script(String strScript)4674 public String script(String strScript) { 4675 // JmolViewer -- just an alias for evalString 4676 return evalStringQuietSync(strScript, false, true); 4677 } 4678 4679 @Override evalString(String strScript)4680 public String evalString(String strScript) { 4681 // JmolSimpleViewer 4682 return evalStringQuietSync(strScript, false, true); 4683 } 4684 4685 @Override evalStringQuiet(String strScript)4686 public String evalStringQuiet(String strScript) { 4687 // JmolViewer 4688 return evalStringQuietSync(strScript, true, true); 4689 } 4690 evalStringQuietSync(String strScript, boolean isQuiet, boolean allowSyncScript)4691 public String evalStringQuietSync(String strScript, boolean isQuiet, 4692 boolean allowSyncScript) { 4693 return (getScriptManager() == null ? null 4694 : scm.evalStringQuietSync(strScript, isQuiet, allowSyncScript)); 4695 } 4696 clearScriptQueue()4697 public void clearScriptQueue() { 4698 if (scm != null) 4699 scm.clearQueue(); 4700 } 4701 setScriptQueue(boolean TF)4702 private void setScriptQueue(boolean TF) { 4703 g.useScriptQueue = TF; 4704 if (!TF) 4705 clearScriptQueue(); 4706 } 4707 4708 @Override checkHalt(String str, boolean isInsert)4709 public boolean checkHalt(String str, boolean isInsert) { 4710 return (scm != null && scm.checkHalt(str, isInsert)); 4711 } 4712 4713 // / direct no-queue use: 4714 4715 @Override scriptWait(String strScript)4716 public String scriptWait(String strScript) { 4717 return (String) evalWait("JSON", strScript, 4718 "+scriptStarted,+scriptStatus,+scriptEcho,+scriptTerminated"); 4719 } 4720 4721 @Override scriptWaitStatus(String strScript, String statusList)4722 public Object scriptWaitStatus(String strScript, String statusList) { 4723 // null statusList will return a String 4724 // -- output from PRINT/MESSAGE/ECHO commands or an error message 4725 // otherwise, specific status messages will be created as a Java object 4726 return evalWait("object", strScript, statusList); 4727 } 4728 evalWait(String returnType, String strScript, String statusList)4729 private Object evalWait(String returnType, String strScript, 4730 String statusList) { 4731 //can't do waitForQueue in JavaScript and then wait for the queue: 4732 if (getScriptManager() == null) 4733 return null; 4734 scm.waitForQueue(); 4735 boolean doTranslateTemp = GT.setDoTranslate(false); 4736 Object ret = evalStringWaitStatusQueued(returnType, strScript, statusList, 4737 false, false); 4738 GT.setDoTranslate(doTranslateTemp); 4739 return ret; 4740 } 4741 exitJmol()4742 public void exitJmol() { 4743 if (isApplet && !isJNLP) 4744 return; 4745 if (headlessImageParams != null) { 4746 try { 4747 if (headless) 4748 outputToFile(headlessImageParams); 4749 } catch (Exception e) { 4750 // 4751 } 4752 } 4753 4754 if (Logger.debugging) 4755 Logger.debug("exitJmol -- exiting"); 4756 System.out.flush(); 4757 System.exit(0); 4758 } 4759 scriptCheckRet(String strScript, boolean returnContext)4760 private Object scriptCheckRet(String strScript, boolean returnContext) { 4761 return (getScriptManager() == null ? null 4762 : scm.scriptCheckRet(strScript, returnContext)); 4763 } 4764 4765 @Override scriptCheck(String strScript)4766 public synchronized Object scriptCheck(String strScript) { 4767 return scriptCheckRet(strScript, false); 4768 } 4769 4770 @Override isScriptExecuting()4771 public boolean isScriptExecuting() { 4772 return (eval != null && eval.isExecuting()); 4773 } 4774 4775 @Override haltScriptExecution()4776 public void haltScriptExecution() { 4777 if (eval != null) { 4778 eval.haltExecution(); 4779 eval.stopScriptThreads(); 4780 } 4781 setStringPropertyTok("pathForAllFiles", T.pathforallfiles, ""); 4782 clearTimeouts(); 4783 } 4784 pauseScriptExecution()4785 public void pauseScriptExecution() { 4786 if (eval != null) 4787 eval.pauseExecution(true); 4788 } 4789 resolveDatabaseFormat(String fileName)4790 String resolveDatabaseFormat(String fileName) { 4791 return (hasDatabasePrefix(fileName) 4792 || fileName.indexOf(JC.legacyResolver) >= 0 4793 ? (String) setLoadFormat(fileName, fileName.charAt(0), false) 4794 : fileName); 4795 } 4796 hasDatabasePrefix(String fileName)4797 public static boolean hasDatabasePrefix(String fileName) { 4798 return (fileName.length() != 0 && isDatabaseCode(fileName.charAt(0))); 4799 } 4800 isDatabaseCode(char ch)4801 public static boolean isDatabaseCode(char ch) { 4802 return (ch == '*' // PDBE 4803 || ch == '$' // NCI resolver 4804 || ch == '=' // RCSB model or ligand 4805 || ch == ':' // PubChem 4806 ); 4807 } 4808 4809 /** 4810 * Jmol will either specify a type or look for it in the first character, 4811 * making sure it is found using isDatabaseCode() first. Starting with Jmol 4812 * 13.1.13, we allow a generalized search using =xxx= where xxx is a known or 4813 * user-specified database designation. 4814 * 4815 * @param name 4816 * @param type 4817 * a character to distinguish the type of file, '?' means we are just 4818 * doing an isosurface check 4819 * @param withPrefix 4820 * @return String or String[] 4821 */ setLoadFormat(String name, char type, boolean withPrefix)4822 public Object setLoadFormat(String name, char type, boolean withPrefix) { 4823 String format = null; 4824 String id = name.substring(1); 4825 switch (type) { 4826 case 'c': // cache:local//... legacyResolver.... 4827 return name; 4828 case 'h': 4829 // legacy resolver https:// 4830 checkCIR(false); 4831 return g.nihResolverFormat 4832 + name.substring(name.indexOf("/structure") + 10); 4833 case '=': 4834 if (name.startsWith("==")) { 4835 id = id.substring(1); 4836 type = '#'; 4837 } else if (id.indexOf("/") > 0) { 4838 // =xxxx/.... 4839 try { 4840 int pt = id.indexOf("/"); 4841 String database = id.substring(0, pt); 4842 id = JC.resolveDataBase(database, id.substring(pt + 1), null); 4843 if (id != null && id.startsWith("'")) 4844 id = evaluateExpression(id).toString(); 4845 return (id == null || id.length() == 0 ? name : id); 4846 } catch (Exception e) { 4847 return name; 4848 } 4849 } else { 4850 if (id.endsWith(".mmtf")) { 4851 id = id.substring(0, id.indexOf(".mmtf")); 4852 return JC.resolveDataBase("mmtf", id.toUpperCase(), null); 4853 } 4854 format = g.loadFormat; 4855 } 4856 //$FALL-THROUGH$ 4857 case '#': // ligand 4858 if (format == null) 4859 format = g.pdbLoadLigandFormat; 4860 return JC.resolveDataBase(null, id, format); 4861 case '*': 4862 // European Bioinformatics Institute 4863 int pt = name.lastIndexOf("/"); 4864 if (name.startsWith("*dom/")) { 4865 // *dom/.../.../.../xxxx 4866 id = name.substring(pt + 1); 4867 format = (pt > 4 ? name.substring(5) : "mappings"); 4868 return PT.rep(JC.resolveDataBase("map", id, null), "%TYPE", format); 4869 } else if (name.startsWith("*val/")) { 4870 // *val/.../.../.../xxxx 4871 id = name.substring(pt + 1); 4872 format = (pt > 4 ? name.substring(5) : "validation/outliers/all"); 4873 return PT.rep(JC.resolveDataBase("map", id, null), "%TYPE", format); 4874 } else if (name.startsWith("*rna3d/")) { 4875 // *rna3d/.../.../.../xxxx 4876 id = name.substring(pt + 1); 4877 format = (pt > 6 ? name.substring(6) : "loops"); 4878 return PT.rep(JC.resolveDataBase("rna3d", id, null), "%TYPE", format); 4879 } else if (name.startsWith("*dssr--")) { 4880 id = name.substring(pt + 1); 4881 id = JC.resolveDataBase("dssr", id, null); 4882 return id + "%20" + PT.rep(name.substring(5, pt), " ", "%20"); 4883 } else if (name.startsWith("*dssr/")) { 4884 id = name.substring(pt + 1); 4885 return JC.resolveDataBase("dssr", id, null); 4886 } else if (name.startsWith("*dssr1/")) { 4887 id = name.substring(pt + 1); 4888 return JC.resolveDataBase("dssr1", id, null); 4889 } 4890 // these are processed in SmarterJmolAdapter 4891 String pdbe = "pdbe"; 4892 if (id.length() == 5 && id.charAt(4) == '*') { 4893 pdbe = "pdbe2"; 4894 id = id.substring(0, 4); 4895 } 4896 return JC.resolveDataBase(pdbe, id, null); 4897 case ':': // PubChem 4898 format = g.pubChemFormat; 4899 if (id.equals("")) { 4900 try { 4901 id = "smiles:" + getOpenSmiles(bsA()); 4902 } catch (Exception e) { 4903 // oh well. 4904 } 4905 } 4906 String fl = id.toLowerCase(); 4907 int fi = Integer.MIN_VALUE; 4908 try { 4909 fi = Integer.parseInt(id); 4910 } catch (Exception e) { 4911 // 4912 } 4913 if (fi != Integer.MIN_VALUE) { 4914 id = "cid/" + fi; 4915 } else { 4916 if (fl.startsWith("smiles:")) { 4917 format += "?POST?smiles=" + id.substring(7); 4918 id = "smiles"; 4919 } else if (id.startsWith("cid:") || id.startsWith("inchikey:") 4920 || id.startsWith("cas:")) { 4921 id = id.replace(':', '/'); 4922 } else { 4923 if (fl.startsWith("name:")) 4924 id = id.substring(5); 4925 id = "name/" + PT.escapeUrl(id); 4926 } 4927 } 4928 return PT.formatStringS(format, "FILE", id); 4929 case '$': 4930 checkCIR(false); 4931 if (name.equals("$")) { 4932 try { 4933 id = getOpenSmiles(bsA()); 4934 } catch (Exception e) { 4935 // oh well... 4936 } 4937 } else if (name.startsWith("$$")) { 4938 // 2D version 4939 id = id.substring(1); 4940 if (id.length() == 0) { 4941 try { 4942 id = getOpenSmiles(bsA()); 4943 } catch (Exception e) { 4944 } 4945 } 4946 //http://cactus.nci.nih.gov/chemical/structure/C%28O%29CCC/file?format=sdf 4947 format = PT.rep(g.smilesUrlFormat, "get3d=true", "get3d=false"); 4948 return PT.formatStringS(format, "FILE", PT.escapeUrl(id)); 4949 } 4950 //$FALL-THROUGH$ 4951 case 'M': 4952 case 'N': 4953 case '2': 4954 case 'I': 4955 case 'K': 4956 case 'S': 4957 case 'T': 4958 case '/': 4959 id = PT.escapeUrl(id); 4960 switch (type) { 4961 case 'M': 4962 case 'N': 4963 format = g.nihResolverFormat + "/%FILE/names"; 4964 break; 4965 case '2': 4966 format = g.nihResolverFormat + "/%FILE/image"; 4967 break; 4968 case 'I': 4969 case 'T': 4970 format = g.nihResolverFormat + "/%FILE/stdinchi"; 4971 break; 4972 case 'K': 4973 format = g.nihResolverFormat + "/%FILE/inchikey"; 4974 break; 4975 case 'S': 4976 format = g.nihResolverFormat + "/%FILE/stdinchikey"; 4977 break; 4978 case '/': 4979 format = g.nihResolverFormat + "/%FILE/"; 4980 break; 4981 default: 4982 format = g.smilesUrlFormat; 4983 break; 4984 } 4985 return (withPrefix ? "MOL3D::" : "") 4986 + PT.formatStringS(format, "FILE", id); 4987 case '?': // check only 4988 case '-': // localized version using the PDBe density server and box.... 4989 case '_': // isosurface "=...", but we code that type as '_' 4990 // now *xxxx or =xxxx -- both go to EBI instead of Uppsala, 4991 // as Uppsala is being decommissioned in 2018 4992 boolean isDiff = id.startsWith("*") || id.startsWith("="); 4993 if (isDiff) 4994 id = id.substring(1); 4995 String ciftype = null; 4996 pt = id.indexOf("."); 4997 if (pt >= 0) { 4998 ciftype = id.substring(pt + 1); 4999 id = id.substring(0, pt); 5000 } 5001 boolean checkXray = id.startsWith("density"); 5002 if (checkXray) 5003 id = "em" + id.substring(7); 5004 if (id.equals("emdb") || id.equals("em")) 5005 id += "/"; 5006 if (id.startsWith("em/")) 5007 id = "emdb" + id.substring(2); 5008 if (id.startsWith("emdb/")) { 5009 // *emdb/9357 5010 // *emdb/=6nef 5011 // *emdb/=, *emdb/, *emdb 5012 id = id.substring(5); 5013 if (id.length() == 0) 5014 id = "="; 5015 else if (id.startsWith("*")) 5016 id = "=" + id.substring(1); 5017 String emdext = "#-sigma=10"; 5018 if (id.startsWith("=")) { 5019 id = (id.equals("=") ? getPdbID() 5020 : id.substring(1)); 5021 if (id == null || type == '?') 5022 return id; 5023 String q = JC.resolveDataBase("emdbquery", id, null); 5024 String data = (String) fm.cacheGet(q, false); 5025 if (data == null) { 5026 showString("retrieving " + q, false); 5027 data = getFileAsString(q); 5028 if (data == null) { 5029 showString("EM retrieve failed for " + id, false); 5030 if (!checkXray) 5031 return null; 5032 data = "FAILED"; 5033 } else { 5034 showString(data, false); 5035 } 5036 fm.cachePut(q, data); 5037 } 5038 pt = data.indexOf("EMD-"); 5039 if (pt >= 0) { 5040 id = data.substring(pt + 4); 5041 pt = id.indexOf('\n'); 5042 if (pt > 0) 5043 id = id.substring(0, pt); 5044 pt = id.indexOf(","); 5045 if (pt > 0) { 5046 emdext = "#-cutoff=" + id.substring(pt + 1); 5047 id = id.substring(0, pt); 5048 } 5049 } else { 5050 if (!checkXray) 5051 return null; 5052 emdext = null; 5053 } 5054 } 5055 if (emdext != null) 5056 return JC.resolveDataBase("emdbmap" + (type == '-' ? "server" : ""), id, 5057 null) + emdext; 5058 } 5059 id = JC.resolveDataBase( 5060 (isDiff ? "pdbemapdiff" : "pdbemap") + (type == '-' ? "server" : ""), 5061 id, null); 5062 if ("cif".equals(ciftype)) { 5063 id = id.replace("bcif", "cif"); 5064 } 5065 break; 5066 } 5067 return id; 5068 } 5069 5070 boolean cirChecked; 5071 5072 /** 5073 * Check to see if the resolver is working 5074 * 5075 * @param forceCheck 5076 */ checkCIR(boolean forceCheck)5077 private void checkCIR(boolean forceCheck) { 5078 if (cirChecked && !forceCheck) 5079 return; 5080 try { 5081 g.removeParam("_cirStatus"); 5082 Map<String, Object> m = getModelSetAuxiliaryInfo(); 5083 m.remove("cirInfo"); 5084 Map<String, Object> map = parseJSONMap( 5085 getFileAsString(g.resolverResolver)); 5086 m.put("cirInfo", map); 5087 ms.msInfo = m; 5088 String s = (String) map.get("status"); 5089 g.setO("_cirStatus", s); 5090 g.setCIR((String) map.get("rfc6570Template")); 5091 System.out.println("Viewer.checkCIR _.cirInfo.status = " + s); 5092 } catch (Throwable t) { 5093 System.out.println( 5094 "Viewer.checkCIR failed at " + g.resolverResolver + ": " + t); 5095 } 5096 cirChecked = true; 5097 } 5098 getStandardLabelFormat(int type)5099 public String getStandardLabelFormat(int type) { 5100 switch (type) { 5101 default: 5102 case 0: // standard 5103 return LabelToken.STANDARD_LABEL; 5104 case 1: 5105 return g.defaultLabelXYZ; 5106 case 2: 5107 return g.defaultLabelPDB; 5108 } 5109 } 5110 getAdditionalHydrogens(BS bsAtoms, Lst<Atom> vConnections, int flags)5111 public P3[] getAdditionalHydrogens(BS bsAtoms, Lst<Atom> vConnections, 5112 int flags) { 5113 if (bsAtoms == null) 5114 bsAtoms = bsA(); 5115 int[] nTotal = new int[1]; 5116 P3[][] pts = ms.calculateHydrogens(bsAtoms, nTotal, vConnections, flags); 5117 P3[] points = new P3[nTotal[0]]; 5118 for (int i = 0, pt = 0; i < pts.length; i++) 5119 if (pts[i] != null) 5120 for (int j = 0; j < pts[i].length; j++) 5121 points[pt++] = pts[i][j]; 5122 return points; 5123 } 5124 5125 @Override setMarBond(short marBond)5126 public void setMarBond(short marBond) { 5127 g.bondRadiusMilliAngstroms = marBond; 5128 g.setI("bondRadiusMilliAngstroms", marBond); 5129 setShapeSize(JC.SHAPE_STICKS, marBond * 2, BSUtil.setAll(ms.ac)); 5130 } 5131 5132 private int hoverAtomIndex = -1; 5133 private String hoverText, hoverLabel = "%U"; 5134 private boolean hoverEnabled = true; 5135 setHoverLabel(String strLabel)5136 public void setHoverLabel(String strLabel) { 5137 shm.loadShape(JC.SHAPE_HOVER); 5138 setShapeProperty(JC.SHAPE_HOVER, "label", strLabel); 5139 setHoverEnabled(strLabel != null); 5140 g.setO("_hoverLabel", hoverLabel = strLabel); 5141 if (!hoverEnabled && !sm.haveHoverCallback()) 5142 startHoverWatcher(false); 5143 } 5144 setHoverEnabled(boolean tf)5145 private void setHoverEnabled(boolean tf) { 5146 hoverEnabled = tf; 5147 g.setB("_hoverEnabled", tf); 5148 } 5149 5150 /* 5151 * hoverCallback reports information about the atom being hovered over. 5152 * 5153 * jmolSetCallback("hoverCallback", "myHoverCallback") function 5154 * myHoverCallback(strInfo, iAtom) {} 5155 * 5156 * strInfo == the atom's identity, including x, y, and z coordinates iAtom == 5157 * the index of the atom being hovered over 5158 * 5159 * Viewer.setStatusAtomHovered Hover.setProperty("target") Viewer.hoverOff 5160 * Viewer.hoverOn 5161 */ hoverOn(int atomIndex, boolean isLabel)5162 void hoverOn(int atomIndex, boolean isLabel) { 5163 g.removeParam("_objecthovered"); 5164 g.setI("_atomhovered", atomIndex); 5165 g.setO("_hoverLabel", hoverLabel); 5166 g.setUserVariable("hovered", 5167 SV.getVariable(BSUtil.newAndSetBit(atomIndex))); 5168 if (sm.haveHoverCallback()) 5169 sm.setStatusAtomHovered(atomIndex, getAtomInfoXYZ(atomIndex, false)); 5170 if (!hoverEnabled || eval != null && isScriptExecuting() 5171 || atomIndex == hoverAtomIndex || g.hoverDelayMs == 0 5172 || !slm.isInSelectionSubset(atomIndex)) 5173 return; 5174 String label = (isLabel ? GT.$("Drag to move label") 5175 : g.modelKitMode && modelkit != null 5176 ? (String) modelkit.setProperty("hoverLabel", 5177 Integer.valueOf(atomIndex)) 5178 : null); 5179 5180 shm.loadShape(JC.SHAPE_HOVER); 5181 if (label != null 5182 && (!isLabel || ms.at[atomIndex].isVisible(JC.VIS_LABEL_FLAG))) { 5183 setShapeProperty(JC.SHAPE_HOVER, "specialLabel", label); 5184 } 5185 setShapeProperty(JC.SHAPE_HOVER, "text", hoverText = null); 5186 setShapeProperty(JC.SHAPE_HOVER, "target", 5187 Integer.valueOf(hoverAtomIndex = atomIndex)); 5188 refresh(REFRESH_SYNC_MASK, "hover on atom"); 5189 } 5190 5191 /** 5192 * Hover over an arbitrary point. 5193 * 5194 * @param x 5195 * @param y 5196 * @param text 5197 * @param id 5198 * optional id to set _objecthovered to 5199 * @param pt 5200 * optional pt to set "hovered" to 5201 */ hoverOnPt(int x, int y, String text, String id, T3 pt)5202 public void hoverOnPt(int x, int y, String text, String id, T3 pt) { 5203 // from draw for drawhover on 5204 if (eval != null && isScriptExecuting()) 5205 return; 5206 g.setO("_hoverLabel", text); 5207 if (id != null && pt != null) { 5208 g.setO("_objecthovered", id); 5209 g.setI("_atomhovered", -1); 5210 g.setUserVariable("hovered", SV.getVariable(pt)); 5211 if (sm.haveHoverCallback()) 5212 sm.setStatusObjectHovered(id, text, pt); 5213 } 5214 if (!hoverEnabled) 5215 return; 5216 shm.loadShape(JC.SHAPE_HOVER); 5217 setShapeProperty(JC.SHAPE_HOVER, "xy", P3i.new3(x, y, 0)); 5218 setShapeProperty(JC.SHAPE_HOVER, "target", null); 5219 setShapeProperty(JC.SHAPE_HOVER, "specialLabel", null); 5220 setShapeProperty(JC.SHAPE_HOVER, "text", text); 5221 hoverAtomIndex = -1; 5222 hoverText = text; 5223 refresh(REFRESH_SYNC_MASK, "hover on point"); 5224 } 5225 hoverOff()5226 void hoverOff() { 5227 try { 5228 if (g.modelKitMode 5229 && acm.getBondPickingMode() != ActionManager.PICKING_ROTATE_BOND) 5230 highlight(null); 5231 if (!hoverEnabled) 5232 return; 5233 boolean isHover = (hoverText != null || hoverAtomIndex >= 0); 5234 if (hoverAtomIndex >= 0) { 5235 setShapeProperty(JC.SHAPE_HOVER, "target", null); 5236 hoverAtomIndex = -1; 5237 } 5238 if (hoverText != null) { 5239 setShapeProperty(JC.SHAPE_HOVER, "text", null); 5240 hoverText = null; 5241 } 5242 setShapeProperty(JC.SHAPE_HOVER, "specialLabel", null); 5243 if (isHover) 5244 refresh(REFRESH_SYNC_MASK, "hover off"); 5245 } catch (Exception e) { 5246 // ignore 5247 } 5248 } 5249 5250 @Override setDebugScript(boolean debugScript)5251 public void setDebugScript(boolean debugScript) { 5252 g.debugScript = debugScript; 5253 g.setB("debugScript", debugScript); 5254 if (eval != null) 5255 eval.setDebugging(); 5256 } 5257 clearClickCount()5258 void clearClickCount() { 5259 setTainted(true); 5260 } 5261 5262 public int currentCursor = GenericPlatform.CURSOR_DEFAULT; 5263 setCursor(int cursor)5264 public void setCursor(int cursor) { 5265 if (isKiosk || currentCursor == cursor || multiTouch || !haveDisplay) 5266 return; 5267 apiPlatform.setCursor(currentCursor = cursor, display); 5268 } 5269 setPickingMode(String strMode, int pickingMode)5270 public void setPickingMode(String strMode, int pickingMode) { 5271 if (!haveDisplay) 5272 return; 5273 showSelected = false; 5274 String option = null; 5275 if (strMode != null) { 5276 int pt = strMode.indexOf("_"); 5277 if (pt >= 0) { 5278 option = strMode.substring(pt + 1); 5279 strMode = strMode.substring(0, pt); 5280 } 5281 pickingMode = ActionManager.getPickingMode(strMode); 5282 } 5283 if (pickingMode < 0) 5284 pickingMode = ActionManager.PICKING_IDENTIFY; 5285 acm.setPickingMode(pickingMode); 5286 g.setO("picking", 5287 ActionManager.getPickingModeName(acm.getAtomPickingMode())); 5288 if (option == null || option.length() == 0) 5289 return; 5290 option = Character.toUpperCase(option.charAt(0)) 5291 + (option.length() == 1 ? "" : option.substring(1, 2)); 5292 switch (pickingMode) { 5293 case ActionManager.PICKING_ASSIGN_ATOM: 5294 getModelkit(false).setProperty("atomType", option); 5295 break; 5296 case ActionManager.PICKING_ASSIGN_BOND: 5297 getModelkit(false).setProperty("bondType", option); 5298 break; 5299 default: 5300 Logger.error("Bad picking mode: " + strMode + "_" + option); 5301 } 5302 } 5303 getPickingMode()5304 public int getPickingMode() { 5305 return (haveDisplay ? acm.getAtomPickingMode() : 0); 5306 } 5307 setPickingStyle(String style, int pickingStyle)5308 void setPickingStyle(String style, int pickingStyle) { 5309 if (!haveDisplay) 5310 return; 5311 if (style != null) 5312 pickingStyle = ActionManager.getPickingStyleIndex(style); 5313 if (pickingStyle < 0) 5314 pickingStyle = ActionManager.PICKINGSTYLE_SELECT_JMOL; 5315 acm.setPickingStyle(pickingStyle); 5316 g.setO("pickingStyle", 5317 ActionManager.getPickingStyleName(acm.getPickingStyle())); 5318 } 5319 getDrawHover()5320 public boolean getDrawHover() { 5321 return haveDisplay && g.drawHover; 5322 } 5323 5324 private P3 ptTemp; 5325 getAtomInfo(int atomOrPointIndex)5326 public String getAtomInfo(int atomOrPointIndex) { 5327 if (ptTemp == null) 5328 ptTemp = new P3(); 5329 // only for MeasurementTable and actionManager 5330 return (atomOrPointIndex >= 0 5331 ? ms.getAtomInfo(atomOrPointIndex, null, ptTemp) 5332 : (String) shm.getShapePropertyIndex(JC.SHAPE_MEASURES, "pointInfo", 5333 -atomOrPointIndex)); 5334 } 5335 getAtomInfoXYZ(int atomIndex, boolean useChimeFormat)5336 private String getAtomInfoXYZ(int atomIndex, boolean useChimeFormat) { 5337 Atom atom = ms.at[atomIndex]; 5338 if (useChimeFormat) 5339 return getChimeMessenger().getInfoXYZ(atom); 5340 if (ptTemp == null) 5341 ptTemp = new P3(); 5342 return atom.getIdentityXYZ(true, ptTemp); 5343 } 5344 5345 // //////////////status manager dispatch////////////// 5346 setSync()5347 private void setSync() { 5348 if (sm.doSync()) 5349 sm.setSync(null); 5350 } 5351 5352 @Override setJmolCallbackListener(JmolCallbackListener listener)5353 public void setJmolCallbackListener(JmolCallbackListener listener) { 5354 sm.cbl = listener; 5355 } 5356 5357 @Override setJmolStatusListener(JmolStatusListener listener)5358 public void setJmolStatusListener(JmolStatusListener listener) { 5359 sm.cbl = sm.jsl = listener; 5360 } 5361 getStatusChanged(String statusNameList)5362 public Lst<Lst<Lst<Object>>> getStatusChanged(String statusNameList) { 5363 return (statusNameList == null ? null 5364 : sm.getStatusChanged(statusNameList)); 5365 } 5366 menuEnabled()5367 public boolean menuEnabled() { 5368 return (!g.disablePopupMenu && getPopupMenu() != null); 5369 } 5370 setStatusDragDropped(int mode, int x, int y, String fileName)5371 public boolean setStatusDragDropped(int mode, int x, int y, String fileName) { 5372 if (mode == 0) { 5373 g.setO("_fileDropped", fileName); 5374 g.setUserVariable("doDrop", SV.vT); 5375 } 5376 boolean handled = sm.setStatusDragDropped(mode, x, y, fileName); 5377 return (!handled || getP("doDrop").toString().equals("true")); 5378 } 5379 5380 /* 5381 * resizeCallback is called whenever the applet gets a resize notification 5382 * from the browser 5383 * 5384 * jmolSetCallback("resizeCallback", "myResizeCallback") function 5385 * myResizeCallback(width, height) {} 5386 */ 5387 setStatusResized(int width, int height)5388 public void setStatusResized(int width, int height) { 5389 sm.setStatusResized(width, height); 5390 } 5391 5392 /* 5393 * scriptCallback is the primary way to monitor script status. In addition, it 5394 * serves to for passing information to the user over the status line of the 5395 * browser as well as to the console. Note that console messages are also sent 5396 * by echoCallback. If messageCallback is enabled but not scriptCallback, 5397 * these messages go to the messageCallback function instead. 5398 * 5399 * jmolSetCallback("scriptCallback", "myScriptCallback") function 5400 * myScriptCallback(app, status, message, intStatus, errorMessageUntranslated) 5401 * {} 5402 * 5403 * intStatus == -2 script start -- message is the script itself intStatus == 0 5404 * general messages during script execution; translated error message may be 5405 * present intStatus >= 1 script termination message; translated and 5406 * untranslated message may be present value is time for execution in 5407 * milliseconds 5408 * 5409 * Eval.defineAtomSet -- compilation bug indicates problem in JmolConstants 5410 * array Eval.instructionDispatchLoop -- debugScript messages 5411 * Eval.logDebugScript -- debugScript messages Eval.pause -- script execution 5412 * paused message Eval.runEval -- "Script completed" message Eval.script -- 5413 * Chime "script <exiting>" message Eval.scriptStatusOrBuffer -- various 5414 * messages for Eval.checkContinue (error message) Eval.connect Eval.delete 5415 * Eval.hbond Eval.load (logMessages message) Eval.message Eval.runEval (error 5416 * message) Eval.write (error reading file) Eval.zap (error message) 5417 * FileManager.createAtomSetCollectionFromFile "requesting..." for Chime-like 5418 * compatibility actionManager.atomPicked 5419 * "pick one more atom in order to spin..." for example 5420 * Viewer.evalStringWaitStatus -- see above -2, 0 only if error, >=1 at 5421 * termination Viewer.reportSelection "xxx atoms selected" 5422 */ 5423 scriptStatus(String strStatus)5424 public void scriptStatus(String strStatus) { 5425 setScriptStatus(strStatus, "", 0, null); 5426 } 5427 scriptStatusMsg(String strStatus, String statusMessage)5428 public void scriptStatusMsg(String strStatus, String statusMessage) { 5429 setScriptStatus(strStatus, statusMessage, 0, null); 5430 } 5431 setScriptStatus(String strStatus, String statusMessage, int msWalltime, String strErrorMessageUntranslated)5432 public void setScriptStatus(String strStatus, String statusMessage, 5433 int msWalltime, 5434 String strErrorMessageUntranslated) { 5435 sm.setScriptStatus(strStatus, statusMessage, msWalltime, 5436 strErrorMessageUntranslated); 5437 } 5438 5439 /* 5440 * syncCallback traps script synchronization messages and allows for 5441 * cancellation (by returning "") or modification 5442 * 5443 * jmolSetCallback("syncCallback", "mySyncCallback") function 5444 * mySyncCallback(app, script, appletName) { ...[modify script here]... return 5445 * newScript } 5446 * 5447 * StatusManager.syncSend Viewer.setSyncTarget Viewer.syncScript 5448 */ 5449 5450 @Override showUrl(String urlString)5451 public void showUrl(String urlString) { 5452 // applet.Jmol 5453 // app Jmol 5454 // StatusManager 5455 if (urlString == null) 5456 return; 5457 if (urlString.indexOf(":") < 0) { 5458 String base = fm.getAppletDocumentBase(); 5459 if (base == "") 5460 base = fm.getFullPathName(false); 5461 if (base.indexOf("/") >= 0) { 5462 base = base.substring(0, base.lastIndexOf("/") + 1); 5463 } else if (base.indexOf("\\") >= 0) { 5464 base = base.substring(0, base.lastIndexOf("\\") + 1); 5465 } 5466 urlString = base + urlString; 5467 } 5468 Logger.info("showUrl:" + urlString); 5469 sm.showUrl(urlString); 5470 } 5471 5472 /** 5473 * an external applet or app with class that extends org.jmol.jvxl.MeshCreator 5474 * might execute: 5475 * 5476 * org.jmol.viewer.Viewer vwr = applet.getViewer(); vwr.setMeshCreator(this); 5477 * 5478 * then that class's updateMesh(String id) method will be called whenever a 5479 * mesh is rendered. 5480 * 5481 * @param meshCreator 5482 */ setMeshCreator(Object meshCreator)5483 public void setMeshCreator(Object meshCreator) { 5484 shm.loadShape(JC.SHAPE_ISOSURFACE); 5485 setShapeProperty(JC.SHAPE_ISOSURFACE, "meshCreator", meshCreator); 5486 } 5487 showConsole(boolean showConsole)5488 public void showConsole(boolean showConsole) { 5489 if (!haveDisplay) 5490 return; 5491 // Eval 5492 try { 5493 if (appConsole == null && showConsole) 5494 getConsole(); 5495 appConsole.setVisible(true); 5496 } catch (Throwable e) { 5497 // no console for this client... maybe no Swing 5498 } 5499 } 5500 getConsole()5501 public JmolAppConsoleInterface getConsole() { 5502 getProperty("DATA_API", "getAppConsole", Boolean.TRUE); 5503 return appConsole; 5504 } 5505 5506 @Override getParameter(String key)5507 public Object getParameter(String key) { 5508 return getP(key); 5509 } 5510 getP(String key)5511 public Object getP(String key) { 5512 return g.getParameter(key, true); 5513 } 5514 getPOrNull(String key)5515 public Object getPOrNull(String key) { 5516 return g.getParameter(key, false); 5517 } 5518 unsetProperty(String key)5519 public void unsetProperty(String key) { 5520 key = key.toLowerCase(); 5521 if (key.equals("all") || key.equals("variables")) 5522 fm.setPathForAllFiles(""); 5523 g.unsetUserVariable(key); 5524 } 5525 5526 @Override notifyStatusReady(boolean isReady)5527 public void notifyStatusReady(boolean isReady) { 5528 System.out.println( 5529 "Jmol applet " + fullName + (isReady ? " ready" : " destroyed")); 5530 if (!isReady) 5531 dispose(); 5532 sm.setStatusAppletReady(fullName, isReady); 5533 } 5534 5535 @Override getBooleanProperty(String key)5536 public boolean getBooleanProperty(String key) { 5537 key = key.toLowerCase(); 5538 if (g.htBooleanParameterFlags.containsKey(key)) 5539 return g.htBooleanParameterFlags.get(key).booleanValue(); 5540 // special cases 5541 if (key.endsWith("p!")) { 5542 if (acm == null) 5543 return false; 5544 String s = acm.getPickingState().toLowerCase(); 5545 key = key.substring(0, key.length() - 2) + ";"; 5546 return (s.indexOf(key) >= 0); 5547 } 5548 if (key.equalsIgnoreCase("executionPaused")) 5549 return (eval != null && eval.isPaused()); 5550 if (key.equalsIgnoreCase("executionStepping")) 5551 return (eval != null && eval.isStepping()); 5552 if (key.equalsIgnoreCase("haveBFactors")) 5553 return (ms.getBFactors() != null); 5554 if (key.equalsIgnoreCase("colorRasmol")) 5555 return cm.isDefaultColorRasmol; 5556 if (key.equalsIgnoreCase("frank")) 5557 return getShowFrank(); 5558 if (key.equalsIgnoreCase("spinOn")) 5559 return tm.spinOn; 5560 if (key.equalsIgnoreCase("isNavigating")) 5561 return tm.isNavigating(); 5562 if (key.equalsIgnoreCase("showSelections")) 5563 return selectionHalosEnabled; 5564 if (g.htUserVariables.containsKey(key)) { 5565 SV t = g.getUserVariable(key); 5566 if (t.tok == T.on) 5567 return true; 5568 if (t.tok == T.off) 5569 return false; 5570 } 5571 Logger.error("vwr.getBooleanProperty(" + key + ") - unrecognized"); 5572 return false; 5573 } 5574 5575 @Override getInt(int tok)5576 public int getInt(int tok) { 5577 switch (tok) { 5578 case T.animationfps: 5579 return am.animationFps; 5580 case T.dotdensity: 5581 return g.dotDensity; 5582 case T.dotscale: 5583 return g.dotScale; 5584 case T.helixstep: 5585 return g.helixStep; 5586 case T.infofontsize: 5587 return g.infoFontSize; 5588 case T.meshscale: 5589 return g.meshScale; 5590 case T.minpixelselradius: 5591 return g.minPixelSelRadius; 5592 case T.percentvdwatom: 5593 return g.percentVdwAtom; 5594 case T.pickingspinrate: 5595 return g.pickingSpinRate; 5596 case T.ribbonaspectratio: 5597 return g.ribbonAspectRatio; 5598 case T.showscript: 5599 return g.scriptDelay; 5600 case T.minimizationmaxatoms: 5601 return g.minimizationMaxAtoms; 5602 case T.smallmoleculemaxatoms: 5603 return g.smallMoleculeMaxAtoms; 5604 case T.strutspacing: 5605 return g.strutSpacing; 5606 case T.vectortrail: 5607 return g.vectorTrail; 5608 } 5609 Logger.error("viewer.getInt(" + T.nameOf(tok) + ") - not listed"); 5610 return 0; 5611 } 5612 5613 // special cases: 5614 getDelayMaximumMs()5615 public int getDelayMaximumMs() { 5616 return (haveDisplay ? g.delayMaximumMs : 1); 5617 } 5618 getHermiteLevel()5619 public int getHermiteLevel() { 5620 return (tm.spinOn && g.hermiteLevel > 0 ? 0 : g.hermiteLevel); 5621 } 5622 getHoverDelay()5623 public int getHoverDelay() { 5624 return (g.modelKitMode ? 20 : g.hoverDelayMs); 5625 5626 } 5627 5628 @Override getBoolean(int tok)5629 public boolean getBoolean(int tok) { 5630 switch (tok) { 5631 case T.nbocharges: 5632 return g.nboCharges; 5633 case T.hiddenlinesdashed: 5634 return g.hiddenLinesDashed; 5635 case T.pdb: 5636 return ms.getMSInfoB("isPDB"); 5637 case T.autoplaymovie: 5638 return g.autoplayMovie; 5639 case T.allowaudio: 5640 return !headless && g.allowAudio; 5641 case T.allowgestures: 5642 return g.allowGestures; 5643 case T.allowmultitouch: 5644 return g.allowMultiTouch; 5645 case T.allowrotateselected: 5646 return g.allowRotateSelected; 5647 case T.appendnew: 5648 return g.appendNew; 5649 case T.applysymmetrytobonds: 5650 return g.applySymmetryToBonds; 5651 case T.atompicking: 5652 return g.atomPicking; 5653 case T.autobond: 5654 return g.autoBond; 5655 case T.autofps: 5656 return g.autoFps; 5657 case T.axesorientationrasmol: 5658 return g.axesOrientationRasmol; 5659 case T.cartoonsteps: 5660 return g.cartoonSteps; 5661 case T.cartoonblocks: 5662 return g.cartoonBlocks; 5663 case T.checkcir: 5664 return g.checkCIR; 5665 case T.bondmodeor: 5666 return g.bondModeOr; 5667 case T.cartoonbaseedges: 5668 return g.cartoonBaseEdges; 5669 case T.cartoonsfancy: 5670 return g.cartoonFancy; 5671 case T.cartoonladders: 5672 return g.cartoonLadders; 5673 case T.cartoonribose: 5674 return g.cartoonRibose; 5675 case T.cartoonrockets: 5676 return g.cartoonRockets; 5677 case T.chaincasesensitive: 5678 return g.chainCaseSensitive || chainCaseSpecified; 5679 case T.ciprule6full: 5680 return g.cipRule6Full; 5681 case T.debugscript: 5682 return g.debugScript; 5683 case T.defaultstructuredssp: 5684 return g.defaultStructureDSSP; 5685 case T.disablepopupmenu: 5686 return g.disablePopupMenu; 5687 case T.displaycellparameters: 5688 return g.displayCellParameters; 5689 case T.dotsurface: 5690 return g.dotSurface; 5691 case T.dotsselectedonly: 5692 return g.dotsSelectedOnly; 5693 case T.drawpicking: 5694 return g.drawPicking; 5695 case T.fontcaching: 5696 return g.fontCaching; 5697 case T.fontscaling: 5698 return g.fontScaling; 5699 case T.forceautobond: 5700 return g.forceAutoBond; 5701 case T.fractionalrelative: 5702 return false;//g.fractionalRelative; 5703 case T.greyscalerendering: 5704 return g.greyscaleRendering; 5705 case T.hbondsbackbone: 5706 return g.hbondsBackbone; 5707 case T.hbondsrasmol: 5708 return g.hbondsRasmol; 5709 case T.hbondssolid: 5710 return g.hbondsSolid; 5711 case T.hetero: 5712 return g.rasmolHeteroSetting; 5713 case T.hidenameinpopup: 5714 return g.hideNameInPopup; 5715 case T.highresolution: 5716 return g.highResolutionFlag; 5717 case T.hydrogen: 5718 return g.rasmolHydrogenSetting; 5719 case T.isosurfacekey: 5720 return g.isosurfaceKey; 5721 case T.jmolinjspecview: 5722 return g.jmolInJSpecView; 5723 case T.justifymeasurements: 5724 return g.justifyMeasurements; 5725 case T.legacyautobonding: 5726 // aargh -- BitSet efficiencies in Jmol 11.9.24, 2/3/2010, meant that 5727 // state files created before that that use select BONDS will select the 5728 // wrong bonds. 5729 // reset after a state script is read 5730 return g.legacyAutoBonding; 5731 case T.legacyhaddition: 5732 // aargh -- Some atoms missed before Jmol 13.1.17 5733 return g.legacyHAddition; 5734 case T.legacyjavafloat: 5735 return g.legacyJavaFloat; 5736 case T.loggestures: 5737 return g.logGestures; 5738 case T.measureallmodels: 5739 return g.measureAllModels; 5740 case T.measurementlabels: 5741 return g.measurementLabels; 5742 case T.messagestylechime: 5743 return g.messageStyleChime; 5744 case T.modelkitmode: 5745 return g.modelKitMode; 5746 case T.multiplebondbananas: 5747 return g.multipleBondBananas; 5748 case T.navigationmode: 5749 return g.navigationMode; 5750 case T.navigationperiodic: 5751 return g.navigationPeriodic; 5752 case T.partialdots: 5753 return g.partialDots; 5754 case T.pdbaddhydrogens: 5755 return g.pdbAddHydrogens; 5756 case T.pdbsequential: 5757 return g.pdbSequential; 5758 case T.preservestate: 5759 return g.preserveState; 5760 case T.refreshing: 5761 return refreshing; 5762 case T.ribbonborder: 5763 return g.ribbonBorder; 5764 case T.rocketbarrels: 5765 return g.rocketBarrels; 5766 case T.nodelay: 5767 return g.noDelay; 5768 case T.selectallmodels: 5769 return g.selectAllModels; 5770 case T.showhiddenselectionhalos: 5771 return g.showHiddenSelectionHalos; 5772 case T.showhydrogens: 5773 return g.showHydrogens; 5774 case T.showmeasurements: 5775 return g.showMeasurements; 5776 case T.showmodvecs: 5777 return g.showModVecs; 5778 case T.showmultiplebonds: 5779 return g.showMultipleBonds; 5780 case T.showtiming: 5781 return g.showTiming; 5782 case T.showunitcelldetails: 5783 return g.showUnitCellDetails; 5784 case T.slabbyatom: 5785 return g.slabByAtom; 5786 case T.slabbymolecule: 5787 return g.slabByMolecule; 5788 case T.smartaromatic: 5789 return g.smartAromatic; 5790 case T.solventprobe: 5791 return g.dotSolvent; 5792 case T.ssbondsbackbone: 5793 return g.ssbondsBackbone; 5794 case T.strutsmultiple: 5795 return g.strutsMultiple; 5796 case T.testflag1: 5797 // CIPChirality -- turns off tracking (skip creation of _M.CIPInfo for speed tests) 5798 // no PNGJ caching 5799 // debug mouse actions 5800 return g.testFlag1; 5801 case T.testflag2: 5802 // no load processing (jmolscript or 2D file load minimization) 5803 // passed to MOCalcuation, but not used 5804 // nciCalculation special params.testFlag = 2 "absolute" calc. 5805 // GIF reducedColors 5806 // plug-in use variable 5807 return g.testFlag2; 5808 case T.testflag3: 5809 // isosurface numbers 5810 // polyhedra numbers 5811 // pmesh triangles 5812 return g.testFlag3; 5813 case T.testflag4: 5814 // isosurface normals 5815 return g.testFlag4; 5816 5817 case T.tracealpha: 5818 return g.traceAlpha; 5819 case T.translucent: 5820 return g.translucent; 5821 case T.twistedsheets: 5822 return g.twistedSheets; 5823 case T.vectorscentered: 5824 return g.vectorsCentered; 5825 case T.vectorsymmetry: 5826 return g.vectorSymmetry; 5827 case T.waitformoveto: 5828 return g.waitForMoveTo; 5829 case T.zerobasedxyzrasmol: 5830 return g.zeroBasedXyzRasmol; 5831 } 5832 Logger.error("viewer.getBoolean(" + T.nameOf(tok) + ") - not listed"); 5833 return false; 5834 } 5835 5836 // special cases: 5837 allowEmbeddedScripts()5838 public boolean allowEmbeddedScripts() { 5839 return (g.allowEmbeddedScripts && !isPreviewOnly); 5840 } 5841 getDragSelected()5842 boolean getDragSelected() { 5843 return (g.dragSelected && !g.modelKitMode); 5844 } 5845 getBondsPickable()5846 boolean getBondsPickable() { 5847 return (g.bondPicking || g.modelKitMode 5848 && getModelkitProperty("isMolecular") == Boolean.TRUE); 5849 } 5850 useMinimizationThread()5851 public boolean useMinimizationThread() { 5852 return (g.useMinimizationThread && !autoExit); 5853 } 5854 5855 @Override getFloat(int tok)5856 public float getFloat(int tok) { 5857 switch (tok) { 5858 case T.atoms: 5859 return g.particleRadius; 5860 case T.axesoffset: 5861 return g.axesOffset; 5862 case T.axesscale: 5863 return g.axesScale; 5864 case T.bondtolerance: 5865 return g.bondTolerance; 5866 case T.defaulttranslucent: 5867 return g.defaultTranslucent; 5868 case T.defaultdrawarrowscale: 5869 return g.defaultDrawArrowScale; 5870 case T.dipolescale: 5871 return g.dipoleScale; 5872 case T.drawfontsize: 5873 return g.drawFontSize; 5874 case T.exportscale: 5875 return g.exportScale; 5876 case T.hbondsangleminimum: 5877 return g.hbondsAngleMinimum; 5878 case T.hbondhxdistancemaximum: 5879 return g.hbondHXDistanceMaximum; 5880 case T.hbondnodistancemaximum: 5881 return g.hbondNODistanceMaximum; 5882 case T.loadatomdatatolerance: 5883 return g.loadAtomDataTolerance; 5884 case T.minbonddistance: 5885 return g.minBondDistance; 5886 case T.modulation: 5887 return g.modulationScale; 5888 case T.multiplebondspacing: 5889 return g.multipleBondSpacing; 5890 case T.multiplebondradiusfactor: 5891 return g.multipleBondRadiusFactor; 5892 case T.navigationspeed: 5893 return g.navigationSpeed; 5894 case T.pointgroupdistancetolerance: 5895 return g.pointGroupDistanceTolerance; 5896 case T.pointgrouplineartolerance: 5897 return g.pointGroupLinearTolerance; 5898 case T.rotationradius: 5899 return tm.modelRadius; 5900 case T.sheetsmoothing: 5901 return g.sheetSmoothing; 5902 case T.solventproberadius: 5903 return g.solventProbeRadius; 5904 case T.starwidth: 5905 return g.starWidth; 5906 case T.strutdefaultradius: 5907 return g.strutDefaultRadius; 5908 case T.strutlengthmaximum: 5909 return g.strutLengthMaximum; 5910 case T.vectorscale: 5911 return g.vectorScale; 5912 case T.vibrationperiod: 5913 return g.vibrationPeriod; 5914 case T.cartoonblockheight: 5915 // 14.11.0 5916 return g.cartoonBlockHeight; 5917 } 5918 Logger.error("viewer.getFloat(" + T.nameOf(tok) + ") - not listed"); 5919 return 0; 5920 } 5921 5922 @Override setStringProperty(String key, String value)5923 public void setStringProperty(String key, String value) { 5924 if (value == null || key == null || key.length() == 0) 5925 return; 5926 if (key.charAt(0) == '_') { 5927 g.setO(key, value); 5928 return; 5929 } 5930 int tok = T.getTokFromName(key); 5931 switch (T.getParamType(tok)) { 5932 case T.booleanparam: 5933 setBooleanPropertyTok(key, tok, SV.newV(T.string, value).asBoolean()); 5934 break; 5935 case T.intparam: 5936 setIntPropertyTok(key, tok, SV.newV(T.string, value).asInt()); 5937 break; 5938 case T.floatparam: 5939 setFloatPropertyTok(key, tok, PT.parseFloat(value)); 5940 break; 5941 default: 5942 setStringPropertyTok(key, tok, value); 5943 } 5944 } 5945 setStringPropertyTok(String key, int tok, String value)5946 private void setStringPropertyTok(String key, int tok, String value) { 5947 switch (tok) { 5948 // 14.29.54 new 5949 case T.macrodirectory: 5950 g.macroDirectory = value = (value == null || value.length() == 0 5951 ? JC.defaultMacroDirectory 5952 : value); 5953 macros = null; 5954 break; 5955 // 14.4.10 new 5956 case T.nihresolverformat: 5957 g.nihResolverFormat = value; 5958 break; 5959 // removed for Jmol 14.29.1 5960 // // 14.3.10 (forgot to add these earlier) 5961 // case T.edsurlcutoff: 5962 // g.edsUrlCutoff = value; 5963 // break; 5964 // case T.edsurlformat: 5965 // g.edsUrlFormat = value; 5966 // break; 5967 // // 14.3.10 new 5968 // case T.edsurlformatdiff: 5969 // g.edsUrlFormatDiff = value; 5970 // break; 5971 // 13.3.6 5972 case T.animationmode: 5973 setAnimationMode(value); 5974 return; 5975 case T.nmrpredictformat: 5976 // 13.3.4 5977 g.nmrPredictFormat = value; 5978 break; 5979 case T.defaultdropscript: 5980 // 13.1.2 5981 // for File|Open and Drag/drop 5982 g.defaultDropScript = value; 5983 break; 5984 5985 case T.pathforallfiles: 5986 // 12.3.29 5987 value = fm.setPathForAllFiles(value); 5988 break; 5989 case T.energyunits: 5990 // 12.3.26 5991 setUnits(value, false); 5992 return; 5993 case T.forcefield: 5994 // 12.3.25 5995 g.forceField = value = ("UFF".equalsIgnoreCase(value) ? "UFF" 5996 : "UFF2D".equalsIgnoreCase(value) ? "UFF2D" 5997 : "MMFF2D".equalsIgnoreCase(value) ? "MMFF2D" : "MMFF"); 5998 minimizer = null; 5999 break; 6000 case T.nmrurlformat: 6001 // 12.3.3 6002 g.nmrUrlFormat = value; 6003 break; 6004 case T.measurementunits: 6005 setUnits(value, true); 6006 return; 6007 case T.loadligandformat: 6008 // /12.1.51// 6009 g.pdbLoadLigandFormat = value; 6010 break; 6011 // 12.1.50 6012 case T.defaultlabelpdb: 6013 g.defaultLabelPDB = value; 6014 break; 6015 case T.defaultlabelxyz: 6016 g.defaultLabelXYZ = value; 6017 break; 6018 case T.defaultloadfilter: 6019 // 12.0.RC10 6020 g.defaultLoadFilter = value; 6021 break; 6022 case T.logfile: 6023 value = getOutputManager().setLogFile(value); 6024 if (value == null) 6025 return; 6026 break; 6027 case T.filecachedirectory: 6028 // 11.9.21 6029 // not implemented -- application only -- CANNOT BE SET BY STATE 6030 // global.fileCacheDirectory = value; 6031 break; 6032 case T.atomtypes: 6033 // 11.7.7 6034 g.atomTypes = value; 6035 break; 6036 case T.currentlocalpath: 6037 // /11.6.RC15 6038 break; 6039 case T.picklabel: 6040 // /11.5.42 6041 g.pickLabel = value; 6042 break; 6043 case T.quaternionframe: 6044 // /11.5.39// 6045 if (value.length() == 2 && value.startsWith("R")) 6046 // C, P -- straightness from Ramachandran angles 6047 g.quaternionFrame = value.substring(0, 2); 6048 else 6049 g.quaternionFrame = "" + (value.toLowerCase() + "p").charAt(0); 6050 if (!PT.isOneOf(g.quaternionFrame, JC.allowedQuaternionFrames)) 6051 g.quaternionFrame = "p"; 6052 ms.haveStraightness = false; 6053 break; 6054 case T.defaultvdw: 6055 // /11.5.11// 6056 setVdwStr(value); 6057 return; 6058 case T.language: 6059 // /11.1.30// 6060 // fr cs en none, etc. 6061 // also serves to change language for callbacks and menu 6062 new GT(this, value); 6063 String language = GT.getLanguage(); 6064 modelkit = null; 6065 if (jmolpopup != null) { 6066 jmolpopup.jpiDispose(); 6067 jmolpopup = null; 6068 getPopupMenu(); 6069 } 6070 sm.setCallbackFunction("language", language); 6071 value = GT.getLanguage(); 6072 break; 6073 case T.loadformat: 6074 // /11.1.22// 6075 g.loadFormat = value; 6076 break; 6077 case T.backgroundcolor: 6078 // /11.1/// 6079 setObjectColor("background", value); 6080 return; 6081 case T.axis1color: 6082 setObjectColor("axis1", value); 6083 return; 6084 case T.axis2color: 6085 setObjectColor("axis2", value); 6086 return; 6087 case T.axis3color: 6088 setObjectColor("axis3", value); 6089 return; 6090 case T.boundboxcolor: 6091 setObjectColor("boundbox", value); 6092 return; 6093 case T.unitcellcolor: 6094 setObjectColor("unitcell", value); 6095 return; 6096 case T.propertycolorscheme: 6097 setPropertyColorScheme(value, false, false); 6098 break; 6099 case T.hoverlabel: 6100 // a special label for selected atoms 6101 shm.loadShape(JC.SHAPE_HOVER); 6102 setShapeProperty(JC.SHAPE_HOVER, "atomLabel", value); 6103 break; 6104 case T.defaultdistancelabel: 6105 // /11.0/// 6106 g.defaultDistanceLabel = value; 6107 break; 6108 case T.defaultanglelabel: 6109 g.defaultAngleLabel = value; 6110 break; 6111 case T.defaulttorsionlabel: 6112 g.defaultTorsionLabel = value; 6113 break; 6114 case T.defaultloadscript: 6115 g.defaultLoadScript = value; 6116 break; 6117 case T.appletproxy: 6118 fm.setAppletProxy(value); 6119 break; 6120 case T.defaultdirectory: 6121 if (value == null) 6122 value = ""; 6123 value = value.replace('\\', '/'); 6124 g.defaultDirectory = value; 6125 break; 6126 case T.helppath: 6127 g.helpPath = value; 6128 break; 6129 case T.defaults: 6130 if (!value.equalsIgnoreCase("RasMol") && !value.equalsIgnoreCase("PyMOL")) 6131 value = "Jmol"; 6132 setDefaultsType(value); 6133 break; 6134 case T.defaultcolorscheme: 6135 // only two are possible: "jmol" and "rasmol" 6136 setDefaultColors(value.equalsIgnoreCase("rasmol")); 6137 return; 6138 case T.picking: 6139 setPickingMode(value, 0); 6140 return; 6141 case T.pickingstyle: 6142 setPickingStyle(value, 0); 6143 return; 6144 case T.dataseparator: 6145 // just saving this 6146 break; 6147 default: 6148 if (key.toLowerCase().endsWith("callback")) { 6149 sm.setCallbackFunction(key, 6150 (value.length() == 0 || value.equalsIgnoreCase("none") ? null 6151 : value)); 6152 break; 6153 } 6154 if (!g.htNonbooleanParameterValues.containsKey(key.toLowerCase())) { 6155 g.setUserVariable(key, SV.newV(T.string, value)); 6156 return; 6157 } 6158 // a few String parameters may not be tokenized. Save them anyway. 6159 // for example, defaultDirectoryLocal 6160 break; 6161 } 6162 g.setO(key, value); 6163 } 6164 6165 @Override setFloatProperty(String key, float value)6166 public void setFloatProperty(String key, float value) { 6167 if (Float.isNaN(value) || key == null || key.length() == 0) 6168 return; 6169 if (key.charAt(0) == '_') { 6170 g.setF(key, value); 6171 return; 6172 } 6173 int tok = T.getTokFromName(key); 6174 switch (T.getParamType(tok)) { 6175 case T.strparam: 6176 setStringPropertyTok(key, tok, "" + value); 6177 break; 6178 case T.booleanparam: 6179 setBooleanPropertyTok(key, tok, value != 0); 6180 break; 6181 case T.intparam: 6182 setIntPropertyTok(key, tok, (int) value); 6183 break; 6184 default: 6185 setFloatPropertyTok(key, tok, value); 6186 } 6187 } 6188 setFloatPropertyTok(String key, int tok, float value)6189 private void setFloatPropertyTok(String key, int tok, float value) { 6190 switch (tok) { 6191 case T.cartoonblockheight: 6192 // 14.11.0 6193 g.cartoonBlockHeight = value; 6194 break; 6195 case T.modulationscale: 6196 // 14.0.1 6197 ms.setModulation(null, false, null, false); 6198 g.modulationScale = value = Math.max(0.1f, value); 6199 ms.setModulation(null, true, null, false); 6200 break; 6201 case T.particleradius: 6202 // 13.3.9 6203 g.particleRadius = Math.abs(value); 6204 break; 6205 case T.drawfontsize: 6206 // 13.3.6 6207 g.drawFontSize = value; 6208 break; 6209 case T.exportscale: 6210 // 13.1.19 6211 g.exportScale = value; 6212 break; 6213 case T.starwidth: 6214 // 13.1.15 6215 g.starWidth = value; 6216 break; 6217 case T.multiplebondradiusfactor: 6218 // 12.1.11 6219 g.multipleBondRadiusFactor = value; 6220 break; 6221 case T.multiplebondspacing: 6222 // 12.1.11 6223 g.multipleBondSpacing = value; 6224 break; 6225 case T.slabrange: 6226 tm.setSlabRange(value); 6227 break; 6228 case T.minimizationcriterion: 6229 g.minimizationCriterion = value; 6230 break; 6231 case T.gestureswipefactor: 6232 if (haveDisplay) 6233 acm.setGestureSwipeFactor(value); 6234 break; 6235 case T.mousedragfactor: 6236 if (haveDisplay) 6237 acm.setMouseDragFactor(value); 6238 break; 6239 case T.mousewheelfactor: 6240 if (haveDisplay) 6241 acm.setMouseWheelFactor(value); 6242 break; 6243 case T.strutlengthmaximum: 6244 // 11.9.21 6245 g.strutLengthMaximum = value; 6246 break; 6247 case T.strutdefaultradius: 6248 g.strutDefaultRadius = value; 6249 break; 6250 case T.navx: 6251 // 11.7.47 6252 setSpin("X", (int) value); 6253 break; 6254 case T.navy: 6255 setSpin("Y", (int) value); 6256 break; 6257 case T.navz: 6258 setSpin("Z", (int) value); 6259 break; 6260 case T.navfps: 6261 if (Float.isNaN(value)) 6262 return; 6263 setSpin("FPS", (int) value); 6264 break; 6265 case T.loadatomdatatolerance: 6266 g.loadAtomDataTolerance = value; 6267 break; 6268 case T.hbondsangleminimum: 6269 // 11.7.9 6270 g.hbondsAngleMinimum = value; 6271 break; 6272 case T.hbondhxdistancemaximum: 6273 // 14.31.33 6274 g.hbondHXDistanceMaximum = value; 6275 break; 6276 case T.hbondnodistancemaximum: 6277 // 11.7.9 6278 g.hbondNODistanceMaximum = value; 6279 break; 6280 case T.pointgroupdistancetolerance: 6281 // 11.6.RC2// 6282 g.pointGroupDistanceTolerance = value; 6283 break; 6284 case T.pointgrouplineartolerance: 6285 g.pointGroupLinearTolerance = value; 6286 break; 6287 case T.ellipsoidaxisdiameter: 6288 g.ellipsoidAxisDiameter = value; 6289 break; 6290 case T.spinx: 6291 // /11.3.52// 6292 setSpin("x", (int) value); 6293 break; 6294 case T.spiny: 6295 setSpin("y", (int) value); 6296 break; 6297 case T.spinz: 6298 setSpin("z", (int) value); 6299 break; 6300 case T.spinfps: 6301 setSpin("fps", (int) value); 6302 break; 6303 case T.defaultdrawarrowscale: 6304 // /11.3.17// 6305 g.defaultDrawArrowScale = value; 6306 break; 6307 case T.defaulttranslucent: 6308 // /11.1/// 6309 g.defaultTranslucent = value; 6310 break; 6311 case T.axesoffset: 6312 setAxesScale(tok, value); 6313 break; 6314 case T.axesscale: 6315 setAxesScale(tok, value); 6316 break; 6317 case T.visualrange: 6318 tm.visualRangeAngstroms = value; 6319 refresh(REFRESH_REPAINT, "set visualRange"); 6320 break; 6321 case T.navigationdepth: 6322 setNavigationDepthPercent(value); 6323 break; 6324 case T.navigationspeed: 6325 g.navigationSpeed = value; 6326 break; 6327 case T.navigationslab: 6328 tm.setNavigationSlabOffsetPercent(value); 6329 break; 6330 case T.cameradepth: 6331 tm.setCameraDepthPercent(value, false); 6332 refresh(REFRESH_REPAINT, "set cameraDepth"); 6333 // transformManager will set global value for us; 6334 return; 6335 case T.rotationradius: 6336 setRotationRadius(value, true); 6337 return; 6338 case T.hoverdelay: 6339 g.hoverDelayMs = (int) (value * 1000); 6340 break; 6341 case T.sheetsmoothing: 6342 // /11.0/// 6343 g.sheetSmoothing = value; 6344 break; 6345 case T.dipolescale: 6346 value = checkFloatRange(value, -10, 10); 6347 g.dipoleScale = value; 6348 break; 6349 case T.stereodegrees: 6350 tm.setStereoDegrees(value); 6351 break; 6352 case T.vectorscale: 6353 // public -- no need to set 6354 setVectorScale(value); 6355 return; 6356 case T.vibrationperiod: 6357 // public -- no need to set 6358 setVibrationPeriod(value); 6359 return; 6360 case T.vibrationscale: 6361 // public -- no need to set 6362 setVibrationScale(value); 6363 return; 6364 case T.bondtolerance: 6365 setBondTolerance(value); 6366 return; 6367 case T.minbonddistance: 6368 setMinBondDistance(value); 6369 return; 6370 case T.scaleangstromsperinch: 6371 tm.setScaleAngstromsPerInch(value); 6372 break; 6373 case T.solventproberadius: 6374 value = checkFloatRange(value, 0, 10); 6375 g.solventProbeRadius = value; 6376 break; 6377 default: 6378 if (!g.htNonbooleanParameterValues.containsKey(key.toLowerCase())) { 6379 g.setUserVariable(key, SV.newF(value)); 6380 return; 6381 } 6382 } 6383 g.setF(key, value); 6384 } 6385 6386 @Override setIntProperty(String key, int value)6387 public void setIntProperty(String key, int value) { 6388 if (value == Integer.MIN_VALUE || key == null || key.length() == 0) 6389 return; 6390 if (key.charAt(0) == '_') { 6391 g.setI(key, value); 6392 return; 6393 } 6394 int tok = T.getTokFromName(key); 6395 switch (T.getParamType(tok)) { 6396 case T.strparam: 6397 setStringPropertyTok(key, tok, "" + value); 6398 break; 6399 case T.booleanparam: 6400 setBooleanPropertyTok(key, tok, value != 0); 6401 break; 6402 case T.floatparam: 6403 setFloatPropertyTok(key, tok, value); 6404 break; 6405 default: 6406 setIntPropertyTok(key, tok, value); 6407 } 6408 } 6409 setIntPropertyTok(String key, int tok, int value)6410 private void setIntPropertyTok(String key, int tok, int value) { 6411 switch (tok) { 6412 case T.minimizationmaxatoms: 6413 // 14.30.0 6414 g.minimizationMaxAtoms = value; 6415 break; 6416 case T.infofontsize: 6417 g.infoFontSize = Math.max(0, value); 6418 break; 6419 case T.contextdepthmax: 6420 case T.historylevel: 6421 case T.scriptreportinglevel: 6422 value = eval.setStatic(tok, value); 6423 break; 6424 case T.vectortrail: 6425 g.vectorTrail = value; 6426 break; 6427 case T.bondingversion: 6428 // 14.1.11 6429 value = (value == 0 ? Elements.RAD_COV_IONIC_OB1_100_1 6430 : Elements.RAD_COV_BODR_2014_02_22); 6431 g.bondingVersion = Elements.bondingVersion = value; 6432 break; 6433 case T.celshadingpower: 6434 // 13.3.9 6435 gdata.setCelPower(value); 6436 break; 6437 case T.ambientocclusion: 6438 // 13.3.9 6439 gdata.setAmbientOcclusion(value); 6440 break; 6441 case T.platformspeed: 6442 // 13.3.4 6443 g.platformSpeed = Math.min(Math.max(value, 0), 10); // 0 could mean "adjust as needed" 6444 break; 6445 case T.meshscale: 6446 // 12.3.29 6447 g.meshScale = value; 6448 break; 6449 case T.minpixelselradius: 6450 // 12.2.RC6 6451 g.minPixelSelRadius = value; 6452 break; 6453 case T.isosurfacepropertysmoothingpower: 6454 // 12.1.11 6455 g.isosurfacePropertySmoothingPower = value; 6456 break; 6457 case T.repaintwaitms: 6458 // 12.0.RC4 6459 g.repaintWaitMs = value; 6460 break; 6461 case T.smallmoleculemaxatoms: 6462 // 12.0.RC3 6463 g.smallMoleculeMaxAtoms = value; 6464 break; 6465 case T.minimizationsteps: 6466 g.minimizationSteps = value; 6467 break; 6468 case T.strutspacing: 6469 // 11.9.21 6470 g.strutSpacing = value; 6471 break; 6472 case T.phongexponent: 6473 // 11.9.13 6474 value = checkIntRange(value, 0, 1000); 6475 gdata.setPhongExponent(value); 6476 break; 6477 case T.helixstep: 6478 // 11.8.RC3 6479 g.helixStep = value; 6480 ms.haveStraightness = false; 6481 break; 6482 case T.dotscale: 6483 // 12.0.RC25 6484 g.dotScale = value; 6485 break; 6486 case T.dotdensity: 6487 // 11.6.RC2// 6488 g.dotDensity = value; 6489 break; 6490 case T.delaymaximumms: 6491 // 11.5.4// 6492 g.delayMaximumMs = value; 6493 break; 6494 case T.loglevel: 6495 // /11.3.52// 6496 Logger.setLogLevel(value); 6497 Logger.info("logging level set to " + value); 6498 g.setI("logLevel", value); 6499 if (eval != null) 6500 eval.setDebugging(); 6501 return; 6502 case T.axesmode: 6503 setAxesMode(value == 2 ? T.axesunitcell 6504 : value == 1 ? T.axesmolecular : T.axeswindow); 6505 return; 6506 case T.strandcount: 6507 // /11.1/// 6508 setStrandCount(0, value); 6509 return; 6510 case T.strandcountforstrands: 6511 setStrandCount(JC.SHAPE_STRANDS, value); 6512 return; 6513 case T.strandcountformeshribbon: 6514 setStrandCount(JC.SHAPE_MESHRIBBON, value); 6515 return; 6516 case T.perspectivemodel: 6517 // abandoned in 13.1.10 6518 //setPerspectiveModel(value); 6519 return; 6520 case T.showscript: 6521 g.scriptDelay = value; 6522 break; 6523 case T.specularpower: 6524 if (value < 0) 6525 value = checkIntRange(value, -10, -1); 6526 else 6527 value = checkIntRange(value, 0, 100); 6528 gdata.setSpecularPower(value); 6529 break; 6530 case T.specularexponent: 6531 value = checkIntRange(-value, -10, -1); 6532 gdata.setSpecularPower(value); 6533 break; 6534 case T.bondradiusmilliangstroms: 6535 setMarBond((short) value); 6536 // public method -- no need to set 6537 return; 6538 case T.specular: 6539 setBooleanPropertyTok(key, tok, value == 1); 6540 return; 6541 case T.specularpercent: 6542 value = checkIntRange(value, 0, 100); 6543 gdata.setSpecularPercent(value); 6544 break; 6545 case T.diffusepercent: 6546 value = checkIntRange(value, 0, 100); 6547 gdata.setDiffusePercent(value); 6548 break; 6549 case T.ambientpercent: 6550 value = checkIntRange(value, 0, 100); 6551 gdata.setAmbientPercent(value); 6552 break; 6553 case T.zdepth: 6554 tm.zDepthToPercent(value); 6555 break; 6556 case T.zslab: 6557 tm.zSlabToPercent(value); 6558 break; 6559 case T.depth: 6560 tm.depthToPercent(value); 6561 break; 6562 case T.slab: 6563 tm.slabToPercent(value); 6564 break; 6565 case T.zshadepower: 6566 g.zShadePower = value = Math.max(value, 0); 6567 break; 6568 case T.ribbonaspectratio: 6569 g.ribbonAspectRatio = value; 6570 break; 6571 case T.pickingspinrate: 6572 g.pickingSpinRate = (value < 1 ? 1 : value); 6573 break; 6574 case T.animationfps: 6575 setAnimationFps(value); 6576 return; 6577 case T.percentvdwatom: 6578 setPercentVdwAtom(value); 6579 break; 6580 case T.hermitelevel: 6581 g.hermiteLevel = value; 6582 break; 6583 case T.ellipsoiddotcount: // 11.5.30 6584 case T.propertyatomnumbercolumncount: 6585 case T.propertyatomnumberfield: // 11.6.RC16 6586 case T.propertydatacolumncount: 6587 case T.propertydatafield: // 11.1.31 6588 // just save in the hashtable, not in global 6589 break; 6590 default: 6591 // stateversion is not tokenized 6592 if (!g.htNonbooleanParameterValues.containsKey(key)) { 6593 g.setUserVariable(key, SV.newI(value)); 6594 return; 6595 } 6596 } 6597 g.setI(key, value); 6598 } 6599 checkIntRange(int value, int min, int max)6600 private static int checkIntRange(int value, int min, int max) { 6601 return (value < min ? min : value > max ? max : value); 6602 } 6603 checkFloatRange(float value, float min, float max)6604 private static float checkFloatRange(float value, float min, float max) { 6605 return (value < min ? min : value > max ? max : value); 6606 } 6607 6608 @Override setBooleanProperty(String key, boolean value)6609 public void setBooleanProperty(String key, boolean value) { 6610 if (key == null || key.length() == 0) 6611 return; 6612 if (key.charAt(0) == '_') { 6613 g.setB(key, value); 6614 return; 6615 } 6616 int tok = T.getTokFromName(key); 6617 switch (T.getParamType(tok)) { 6618 case T.strparam: 6619 setStringPropertyTok(key, tok, ""); 6620 break; 6621 case T.intparam: 6622 setIntPropertyTok(key, tok, value ? 1 : 0); 6623 break; 6624 case T.floatparam: 6625 setFloatPropertyTok(key, tok, value ? 1 : 0); 6626 break; 6627 default: 6628 setBooleanPropertyTok(key, tok, value); 6629 } 6630 } 6631 setBooleanPropertyTok(String key, int tok, boolean value)6632 private void setBooleanPropertyTok(String key, int tok, boolean value) { 6633 boolean doRepaint = true; 6634 switch (tok) { 6635 case T.checkcir: 6636 // 14.31.40 6637 g.checkCIR = value; 6638 if (value) { 6639 checkCIR(true); 6640 } 6641 break; 6642 case T.ciprule6full: 6643 // 14.29.14 6644 g.cipRule6Full = value; 6645 break; 6646 case T.autoplaymovie: 6647 // 14.29.2 6648 g.autoplayMovie = value; 6649 break; 6650 case T.allowaudio: 6651 // 14.29.2 6652 value = false; 6653 // cannot be set TRUE once set FALSE 6654 g.allowAudio = value; 6655 break; 6656 case T.nodelay: 6657 // 14.21.1 6658 g.noDelay = value; 6659 break; 6660 case T.nbocharges: 6661 // 14.8.2 6662 g.nboCharges = value; 6663 break; 6664 case T.hiddenlinesdashed: 6665 // 14.5.1 6666 g.hiddenLinesDashed = value; 6667 break; 6668 case T.multiplebondbananas: 6669 // 14.3.15 6670 g.multipleBondBananas = value; 6671 break; 6672 case T.modulateoccupancy: 6673 // 12.0.RC6 6674 g.modulateOccupancy = value; 6675 break; 6676 case T.legacyjavafloat: 6677 // 14.3.5 6678 g.legacyJavaFloat = value; 6679 break; 6680 case T.showmodvecs: 6681 // 14.3.5 6682 g.showModVecs = value; 6683 break; 6684 case T.showunitcelldetails: 6685 // 14.1.16 6686 g.showUnitCellDetails = value; 6687 break; 6688 case T.fractionalrelative: 6689 // REMOVED in 14.1.16 6690 // an odd quantity -- relates specifically to scripts commands 6691 // using fx, fy, fz, fxyz, ux, uy, uz, uxyz, and cell= 6692 // It should never have been set in state, as it has nothing to do with the state 6693 // Its use with cell= was never documented. 6694 // It makes no sense to change the unit cell and not change the 6695 // meaning of fx, fy, fz, fxyz, ux, uy, uz, uxyz, and cell= 6696 // Its presence caused unitcell [{origin} {a} {b} {c}] to fail. 6697 6698 //g.fractionalRelative = value; 6699 doRepaint = false; 6700 break; 6701 case T.vectorscentered: 6702 // 14.1.15 6703 g.vectorsCentered = value; 6704 break; 6705 case T.cartoonblocks: 6706 // 14.11.0 6707 g.cartoonBlocks = value; 6708 break; 6709 case T.cartoonsteps: 6710 // 14.1.14 6711 g.cartoonSteps = value; 6712 break; 6713 case T.cartoonribose: 6714 // 14.1.8 6715 g.cartoonRibose = value; 6716 // if (value && getBoolean(T.cartoonbaseedges)) 6717 // setBooleanPropertyTok("cartoonBaseEdges", T.cartoonbaseedges, false); 6718 break; 6719 case T.ellipsoidarrows: 6720 // 13.1.17 TRUE for little points on ellipsoids showing sign of 6721 // eigenvalues (in --> negative; out --> positive) 6722 g.ellipsoidArrows = value; 6723 break; 6724 case T.translucent: 6725 // 13.1.17 false -> translucent objects are opaque among themselves (Pymol transparency_mode 2) 6726 g.translucent = value; 6727 break; 6728 case T.cartoonladders: 6729 // 13.1.15 6730 g.cartoonLadders = value; 6731 break; 6732 case T.twistedsheets: 6733 boolean b = g.twistedSheets; 6734 g.twistedSheets = value; 6735 if (b != value) 6736 checkCoordinatesChanged(); 6737 break; 6738 case T.celshading: 6739 // 13.1.13 6740 gdata.setCel(value); 6741 break; 6742 case T.cartoonsfancy: 6743 // 12.3.7 6744 g.cartoonFancy = value; 6745 break; 6746 case T.showtiming: 6747 // 12.3.6 6748 g.showTiming = value; 6749 break; 6750 case T.vectorsymmetry: 6751 // 12.3.2 6752 g.vectorSymmetry = value; 6753 break; 6754 case T.isosurfacekey: 6755 // 12.2.RC5 6756 g.isosurfaceKey = value; 6757 break; 6758 case T.partialdots: 6759 // Jmol 12.1.46 6760 g.partialDots = value; 6761 break; 6762 case T.legacyautobonding: 6763 g.legacyAutoBonding = value; 6764 break; 6765 case T.defaultstructuredssp: 6766 g.defaultStructureDSSP = value; 6767 break; 6768 case T.dsspcalchydrogen: 6769 g.dsspCalcHydrogen = value; 6770 break; 6771 case T.allowmodelkit: 6772 // 11.12.RC15 6773 g.allowModelkit = value; 6774 if (!value) 6775 setModelKitMode(false); 6776 break; 6777 case T.modelkitmode: 6778 setModelKitMode(value); 6779 break; 6780 case T.multiprocessor: 6781 // 12.0.RC6 6782 g.multiProcessor = value && (nProcessors > 1); 6783 break; 6784 case T.monitorenergy: 6785 // 12.0.RC6 6786 g.monitorEnergy = value; 6787 break; 6788 case T.hbondsrasmol: 6789 // 12.0.RC3 6790 g.hbondsRasmol = value; 6791 break; 6792 case T.minimizationrefresh: 6793 g.minimizationRefresh = value; 6794 break; 6795 case T.minimizationsilent: 6796 // 12.0.RC5 6797 g.minimizationSilent = value; 6798 break; 6799 //case T.usearcball: 6800 //g.useArcBall = value; 6801 //break; 6802 case T.iskiosk: 6803 // 11.9.29 6804 // 12.2.9, 12.3.9: no false here, because it's a one-time setting 6805 if (value) { 6806 isKiosk = true; 6807 g.disablePopupMenu = true; 6808 if (display != null) 6809 apiPlatform.setTransparentCursor(display); 6810 } 6811 break; 6812 // 11.9.28 6813 case T.waitformoveto: 6814 g.waitForMoveTo = value; 6815 break; 6816 case T.logcommands: 6817 g.logCommands = true; 6818 break; 6819 case T.loggestures: 6820 g.logGestures = true; 6821 break; 6822 case T.allowmultitouch: 6823 // 11.9.24 6824 g.allowMultiTouch = value; 6825 break; 6826 case T.preservestate: 6827 // 11.9.23 6828 g.preserveState = value; 6829 ms.setPreserveState(value); 6830 undoClear(); 6831 break; 6832 case T.strutsmultiple: 6833 // 11.9.23 6834 g.strutsMultiple = value; 6835 break; 6836 case T.filecaching: 6837 // 11.9.21 6838 // not implemented -- application only -- CANNOT BE SET BY STATE 6839 break; 6840 case T.slabbyatom: 6841 // 11.9.19 6842 g.slabByAtom = value; 6843 break; 6844 case T.slabbymolecule: 6845 // 11.9.18 6846 g.slabByMolecule = value; 6847 break; 6848 case T.saveproteinstructurestate: 6849 // 11.9.15 6850 g.saveProteinStructureState = value; 6851 break; 6852 case T.allowgestures: 6853 g.allowGestures = value; 6854 break; 6855 case T.imagestate: 6856 // 11.8.RC6 6857 g.imageState = value; 6858 break; 6859 case T.useminimizationthread: 6860 // 11.7.40 6861 g.useMinimizationThread = value; 6862 break; 6863 // case Token.autoloadorientation: 6864 // // 11.7.30; removed in 12.0.RC10 -- use FILTER "NoOrient" 6865 // global.autoLoadOrientation = value; 6866 // break; 6867 case T.allowkeystrokes: 6868 // 11.7.24 6869 // if (g.disablePopupMenu) 6870 // value = false; 6871 g.allowKeyStrokes = value; 6872 break; 6873 case T.dragselected: 6874 // 11.7.24 6875 g.dragSelected = value; 6876 showSelected = false; 6877 break; 6878 case T.showkeystrokes: 6879 g.showKeyStrokes = value; 6880 break; 6881 case T.fontcaching: 6882 // 11.7.10 6883 g.fontCaching = value; 6884 break; 6885 case T.atompicking: 6886 // 11.6.RC13 6887 g.atomPicking = value; 6888 break; 6889 case T.bondpicking: 6890 // 11.6.RC13 6891 highlight(null); 6892 g.bondPicking = value; 6893 break; 6894 case T.selectallmodels: 6895 // 11.5.52 6896 g.selectAllModels = value; 6897 if (value) 6898 slm.setSelectionSubset(null); 6899 else 6900 am.setSelectAllSubset(false); 6901 break; 6902 case T.messagestylechime: 6903 // 11.5.39 6904 g.messageStyleChime = value; 6905 break; 6906 case T.pdbsequential: 6907 g.pdbSequential = value; 6908 break; 6909 case T.pdbaddhydrogens: 6910 g.pdbAddHydrogens = value; 6911 break; 6912 case T.pdbgetheader: 6913 g.pdbGetHeader = value; 6914 break; 6915 case T.ellipsoidaxes: 6916 g.ellipsoidAxes = value; 6917 break; 6918 case T.ellipsoidarcs: 6919 g.ellipsoidArcs = value; 6920 break; 6921 case T.ellipsoidball: 6922 g.ellipsoidBall = value; 6923 break; 6924 case T.ellipsoiddots: 6925 g.ellipsoidDots = value; 6926 break; 6927 case T.ellipsoidfill: 6928 g.ellipsoidFill = value; 6929 break; 6930 case T.fontscaling: 6931 // 11.5.4 6932 g.fontScaling = value; 6933 break; 6934 case T.syncmouse: 6935 // 11.3.56 6936 setSyncTarget(0, value); 6937 break; 6938 case T.syncscript: 6939 setSyncTarget(1, value); 6940 break; 6941 case T.wireframerotation: 6942 // 11.3.55 6943 g.wireframeRotation = value; 6944 break; 6945 case T.isosurfacepropertysmoothing: 6946 // 11.3.46 6947 g.isosurfacePropertySmoothing = value; 6948 break; 6949 case T.drawpicking: 6950 // 11.3.43 6951 g.drawPicking = value; 6952 break; 6953 case T.antialiasdisplay: 6954 // 11.3.36 6955 case T.antialiastranslucent: 6956 case T.antialiasimages: 6957 setAntialias(tok, value); 6958 break; 6959 case T.smartaromatic: 6960 // 11.3.29 6961 g.smartAromatic = value; 6962 break; 6963 case T.applysymmetrytobonds: 6964 // 11.1.29 6965 setApplySymmetryToBonds(value); 6966 break; 6967 case T.appendnew: 6968 // 11.1.22 6969 g.appendNew = value; 6970 break; 6971 case T.autofps: 6972 g.autoFps = value; 6973 break; 6974 case T.usenumberlocalization: 6975 // 11.1.21 6976 DF.setUseNumberLocalization(g.useNumberLocalization = value); 6977 break; 6978 case T.showfrank: 6979 case T.frank: 6980 key = "showFrank"; 6981 setFrankOn(value); 6982 // 11.1.20 6983 break; 6984 case T.solvent: 6985 key = "solventProbe"; 6986 g.dotSolvent = value; 6987 break; 6988 case T.solventprobe: 6989 g.dotSolvent = value; 6990 break; 6991 case T.allowrotateselected: 6992 // 11.1.14 6993 g.allowRotateSelected = value; 6994 break; 6995 case T.allowmoveatoms: 6996 // 12.1.21 6997 //setBooleanProperty("allowRotateSelected", value); 6998 //setBooleanProperty("dragSelected", value); 6999 g.allowMoveAtoms = value; 7000 showSelected = false; 7001 break; 7002 case T.showscript: 7003 // /11.1.13/// 7004 setIntPropertyTok("showScript", tok, value ? 1 : 0); 7005 return; 7006 case T.allowembeddedscripts: 7007 // /11.1/// 7008 g.allowEmbeddedScripts = value; 7009 break; 7010 case T.navigationperiodic: 7011 g.navigationPeriodic = value; 7012 break; 7013 case T.zshade: 7014 tm.setZShadeEnabled(value); 7015 return; 7016 case T.drawhover: 7017 if (haveDisplay) 7018 g.drawHover = value; 7019 break; 7020 case T.navigationmode: 7021 setNavigationMode(value); 7022 break; 7023 case T.navigatesurface: 7024 // was experimental; abandoned in 13.1.10 7025 return;//global.navigateSurface = value; 7026 //break; 7027 case T.hidenavigationpoint: 7028 g.hideNavigationPoint = value; 7029 break; 7030 case T.shownavigationpointalways: 7031 g.showNavigationPointAlways = value; 7032 break; 7033 case T.refreshing: 7034 // /11.0/// 7035 setRefreshing(value); 7036 break; 7037 case T.jmolinjspecview: 7038 g.jmolInJSpecView = value; 7039 break; 7040 case T.justifymeasurements: 7041 g.justifyMeasurements = value; 7042 break; 7043 case T.ssbondsbackbone: 7044 g.ssbondsBackbone = value; 7045 break; 7046 case T.hbondsbackbone: 7047 g.hbondsBackbone = value; 7048 break; 7049 case T.hbondssolid: 7050 g.hbondsSolid = value; 7051 break; 7052 case T.specular: 7053 gdata.setSpecular(value); 7054 break; 7055 case T.slabenabled: 7056 // Eval.slab 7057 tm.setSlabEnabled(value); // refresh? 7058 return; 7059 case T.zoomenabled: 7060 tm.setZoomEnabled(value); 7061 return; 7062 case T.highresolution: 7063 g.highResolutionFlag = value; 7064 break; 7065 case T.tracealpha: 7066 g.traceAlpha = value; 7067 break; 7068 case T.zoomlarge: 7069 g.zoomLarge = value; 7070 tm.setZoomHeight(g.zoomHeight, value); 7071 break; 7072 case T.zoomheight: 7073 g.zoomHeight = value; 7074 tm.setZoomHeight(value, g.zoomLarge); 7075 break; 7076 case T.languagetranslation: 7077 GT.setDoTranslate(value); 7078 break; 7079 case T.hidenotselected: 7080 slm.setHideNotSelected(value); 7081 break; 7082 case T.scriptqueue: 7083 setScriptQueue(value); 7084 break; 7085 case T.dotsurface: 7086 g.dotSurface = value; 7087 break; 7088 case T.dotsselectedonly: 7089 g.dotsSelectedOnly = value; 7090 break; 7091 case T.selectionhalos: 7092 setSelectionHalosEnabled(value); 7093 break; 7094 case T.selecthydrogen: 7095 g.rasmolHydrogenSetting = value; 7096 break; 7097 case T.selecthetero: 7098 g.rasmolHeteroSetting = value; 7099 break; 7100 case T.showmultiplebonds: 7101 g.showMultipleBonds = value; 7102 break; 7103 case T.showhiddenselectionhalos: 7104 g.showHiddenSelectionHalos = value; 7105 break; 7106 case T.windowcentered: 7107 tm.setWindowCentered(value); 7108 break; 7109 case T.displaycellparameters: 7110 g.displayCellParameters = value; 7111 break; 7112 case T.testflag1: 7113 g.testFlag1 = value; 7114 break; 7115 case T.testflag2: 7116 g.testFlag2 = value; 7117 break; 7118 case T.testflag3: 7119 g.testFlag3 = value; 7120 break; 7121 case T.testflag4: 7122 jmolTest(); 7123 g.testFlag4 = value; 7124 break; 7125 case T.ribbonborder: 7126 g.ribbonBorder = value; 7127 break; 7128 case T.cartoonbaseedges: 7129 g.cartoonBaseEdges = value; 7130 // if (value && getBoolean(T.cartoonribose)) 7131 // setBooleanPropertyTok("cartoonRibose", T.cartoonribose, false); 7132 break; 7133 case T.cartoonrockets: 7134 g.cartoonRockets = value; 7135 break; 7136 case T.rocketbarrels: 7137 g.rocketBarrels = value; 7138 break; 7139 case T.greyscalerendering: 7140 gdata.setGreyscaleMode(g.greyscaleRendering = value); 7141 break; 7142 case T.measurementlabels: 7143 g.measurementLabels = value; 7144 break; 7145 case T.axeswindow: 7146 case T.axesmolecular: 7147 case T.axesunitcell: 7148 setAxesMode(tok); 7149 return; 7150 case T.axesorientationrasmol: 7151 // public; no need to set here 7152 setAxesOrientationRasmol(value); 7153 return; 7154 case T.colorrasmol: 7155 setStringPropertyTok("defaultcolorscheme", T.defaultcolorscheme, 7156 value ? "rasmol" : "jmol"); 7157 return; 7158 case T.debugscript: 7159 setDebugScript(value); 7160 return; 7161 case T.perspectivedepth: 7162 setPerspectiveDepth(value); 7163 return; 7164 case T.autobond: 7165 // public - no need to set 7166 setAutoBond(value); 7167 return; 7168 case T.showaxes: 7169 setShowAxes(value); 7170 return; 7171 case T.showboundbox: 7172 setShowBbcage(value); 7173 return; 7174 case T.showhydrogens: 7175 setShowHydrogens(value); 7176 return; 7177 case T.showmeasurements: 7178 setShowMeasurements(value); 7179 return; 7180 case T.showunitcell: 7181 setShowUnitCell(value); 7182 return; 7183 case T.bondmodeor: 7184 doRepaint = false; 7185 g.bondModeOr = value; 7186 break; 7187 case T.zerobasedxyzrasmol: 7188 doRepaint = false; 7189 g.zeroBasedXyzRasmol = value; 7190 reset(true); 7191 break; 7192 case T.rangeselected: 7193 doRepaint = false; 7194 g.rangeSelected = value; 7195 break; 7196 case T.measureallmodels: 7197 doRepaint = false; 7198 g.measureAllModels = value; 7199 break; 7200 case T.statusreporting: 7201 doRepaint = false; 7202 // not part of the state 7203 sm.allowStatusReporting = value; 7204 break; 7205 case T.chaincasesensitive: 7206 doRepaint = false; 7207 g.chainCaseSensitive = value; 7208 break; 7209 case T.hidenameinpopup: 7210 doRepaint = false; 7211 g.hideNameInPopup = value; 7212 break; 7213 case T.disablepopupmenu: 7214 doRepaint = false; 7215 g.disablePopupMenu = value; 7216 break; 7217 case T.forceautobond: 7218 doRepaint = false; 7219 g.forceAutoBond = value; 7220 break; 7221 default: 7222 if (!g.htBooleanParameterFlags.containsKey(key.toLowerCase())) { 7223 g.setUserVariable(key, SV.getBoolean(value)); 7224 return; 7225 } 7226 } 7227 g.setB(key, value); 7228 if (doRepaint) 7229 setTainted(true); 7230 } 7231 7232 /* 7233 * public void setFileCacheDirectory(String fileOrDir) { if (fileOrDir == 7234 * null) fileOrDir = ""; global._fileCache = fileOrDir; } 7235 * 7236 * String getFileCacheDirectory() { if (!global._fileCaching) return null; 7237 * return global._fileCache; } 7238 */ 7239 setModelKitMode(boolean value)7240 private void setModelKitMode(boolean value) { 7241 if (acm == null || !allowScripting) 7242 return; 7243 if (value || g.modelKitMode) { 7244 setPickingMode(null, value ? ActionManager.PICKING_ASSIGN_BOND 7245 : ActionManager.PICKING_IDENTIFY); 7246 setPickingMode(null, value ? ActionManager.PICKING_ASSIGN_ATOM 7247 : ActionManager.PICKING_IDENTIFY); 7248 } 7249 boolean isChange = (g.modelKitMode != value); 7250 g.modelKitMode = value; 7251 g.setB("modelkitmode", value); // in case there is a callback before this completes 7252 highlight(null); 7253 if (value) { 7254 ModelKitPopup kit = getModelkit(false); 7255 setNavigationMode(false); 7256 selectAll(); 7257 // setShapeProperty(JmolConstants.SHAPE_LABELS, "color", "RED"); 7258 kit.setProperty("atomType", "C"); 7259 kit.setProperty("bondType", "p"); 7260 if (!isApplet) 7261 popupMenu(10, 0, 'm'); // was 0? 7262 if (isChange) 7263 sm.setStatusModelKit(1); 7264 g.modelKitMode = true; 7265 if (ms.ac == 0) 7266 zap(false, true, true); 7267 else if (am.cmi >= 0 && getModelUndeletedAtomsBitSet(am.cmi).isEmpty()) { 7268 Map<String, Object> htParams = new Hashtable<String, Object>(); 7269 htParams.put("appendToModelIndex", Integer.valueOf(am.cmi)); 7270 loadDefaultModelKitModel(htParams); 7271 } 7272 } else { 7273 acm.setPickingMode(ActionManager.PICKING_MK_RESET); 7274 setStringProperty("pickingStyle", "toggle"); 7275 setBooleanProperty("bondPicking", false); 7276 if (isChange) { 7277 sm.setStatusModelKit(0); 7278 } 7279 } 7280 } 7281 setSmilesString(String s)7282 public void setSmilesString(String s) { 7283 if (s == null) 7284 g.removeParam("_smilesString"); 7285 else 7286 g.setO("_smilesString", s); 7287 } 7288 removeUserVariable(String key)7289 public void removeUserVariable(String key) { 7290 g.removeUserVariable(key); 7291 if (key.endsWith("callback")) 7292 sm.setCallbackFunction(key, null); 7293 } 7294 jmolTest()7295 private void jmolTest() { 7296 /* 7297 * Vector v = new Vector(); Vector m = new Vector(); v.add(m); 7298 * m.add("MODEL 2");m.add( 7299 * "HETATM 1 H1 UNK 1 2.457 0.000 0.000 1.00 0.00 H " 7300 * );m.add( 7301 * "HETATM 2 C1 UNK 1 1.385 0.000 0.000 1.00 0.00 C " 7302 * );m.add( 7303 * "HETATM 3 C2 UNK 1 -1.385 -0.000 0.000 1.00 0.00 C " 7304 * ); v.add(new String[] { "MODEL 2", 7305 * "HETATM 1 H1 UNK 1 2.457 0.000 0.000 1.00 0.00 H " 7306 * , 7307 * "HETATM 2 C1 UNK 1 1.385 0.000 0.000 1.00 0.00 C " 7308 * , 7309 * "HETATM 3 C2 UNK 1 -1.385 -0.000 0.000 1.00 0.00 C " 7310 * , }); v.add(new String[] {"3","testing","C 0 0 0","O 0 1 0","N 0 0 1"} ); 7311 * v.add("3\ntesting\nC 0 0 0\nO 0 1 0\nN 0 0 1\n"); loadInline(v, false); 7312 */ 7313 } 7314 showParameter(String key, boolean ifNotSet, int nMax)7315 public void showParameter(String key, boolean ifNotSet, int nMax) { 7316 String sv = "" + g.getParameterEscaped(key, nMax); 7317 if (ifNotSet || sv.indexOf("<not defined>") < 0) 7318 showString(key + " = " + sv, false); 7319 } 7320 showString(String str, boolean isPrint)7321 public void showString(String str, boolean isPrint) { 7322 if (!isJS && isScriptQueued() && (!isSilent || isPrint) 7323 && !"\0".equals(str)) { 7324 Logger.warn(str); // warn here because we still want to be be able to turn this off 7325 } 7326 scriptEcho(str); 7327 } 7328 getAllSettings(String prefix)7329 public String getAllSettings(String prefix) { 7330 return getStateCreator().getAllSettings(prefix); 7331 } 7332 getBindingInfo(String qualifiers)7333 public String getBindingInfo(String qualifiers) { 7334 return (haveDisplay ? acm.getBindingInfo(qualifiers) : ""); 7335 } 7336 7337 // ////// flags and settings //////// 7338 getIsosurfacePropertySmoothing(boolean asPower)7339 public int getIsosurfacePropertySmoothing(boolean asPower) { 7340 // Eval 7341 return (asPower ? g.isosurfacePropertySmoothingPower 7342 : g.isosurfacePropertySmoothing ? 1 : 0); 7343 } 7344 setNavigationDepthPercent(float percent)7345 public void setNavigationDepthPercent(float percent) { 7346 tm.setNavigationDepthPercent(percent); 7347 refresh(REFRESH_REPAINT, "set navigationDepth"); 7348 } 7349 getShowNavigationPoint()7350 public boolean getShowNavigationPoint() { 7351 if (!g.navigationMode/* || !tm.canNavigate()*/) 7352 return false; 7353 return (tm.isNavigating() && !g.hideNavigationPoint 7354 || g.showNavigationPointAlways || getInMotion(true)); 7355 } 7356 7357 @Override setPerspectiveDepth(boolean perspectiveDepth)7358 public void setPerspectiveDepth(boolean perspectiveDepth) { 7359 // setBooleanProperty 7360 // stateManager.setCrystallographicDefaults 7361 // app preferences dialog 7362 tm.setPerspectiveDepth(perspectiveDepth); 7363 } 7364 7365 @Override setAxesOrientationRasmol(boolean TF)7366 public void setAxesOrientationRasmol(boolean TF) { 7367 // app PreferencesDialog 7368 // stateManager 7369 // setBooleanproperty 7370 /* 7371 * *************************************************************** RasMol 7372 * has the +Y axis pointing down And rotations about the y axis are 7373 * left-handed setting this flag makes Jmol mimic this behavior 7374 * 7375 * All versions of Jmol prior to 11.5.51 incompletely implement this flag. 7376 * All versions of Jmol between 11.5.51 and 12.2.4 incorrectly implement this flag. 7377 * Really all it is just a flag to tell Eval to flip the sign of the Z 7378 * rotation when specified specifically as "rotate/spin Z 30". 7379 * 7380 * In principal, we could display the axis opposite as well, but that is 7381 * only aesthetic and not at all justified if the axis is molecular. 7382 * ************************************************************** 7383 */ 7384 g.setB("axesOrientationRasmol", TF); 7385 g.axesOrientationRasmol = TF; 7386 reset(true); 7387 } 7388 setAxesScale(int tok, float val)7389 private void setAxesScale(int tok, float val) { 7390 val = checkFloatRange(val, -100, 100); 7391 if (tok == T.axesoffset) 7392 g.axesOffset = val; 7393 else 7394 g.axesScale = val; 7395 axesAreTainted = true; 7396 } 7397 setAxesMode(int mode)7398 void setAxesMode(int mode) { 7399 g.axesMode = mode; 7400 axesAreTainted = true; 7401 switch (mode) { 7402 case T.axesunitcell: 7403 // stateManager 7404 // setBooleanproperty 7405 g.removeParam("axesmolecular"); 7406 g.removeParam("axeswindow"); 7407 g.setB("axesUnitcell", true); 7408 mode = 2; 7409 break; 7410 case T.axesmolecular: 7411 g.removeParam("axesunitcell"); 7412 g.removeParam("axeswindow"); 7413 g.setB("axesMolecular", true); 7414 mode = 1; 7415 break; 7416 case T.axeswindow: 7417 g.removeParam("axesunitcell"); 7418 g.removeParam("axesmolecular"); 7419 g.setB("axesWindow", true); 7420 mode = 0; 7421 } 7422 g.setI("axesMode", mode); 7423 } 7424 7425 private boolean selectionHalosEnabled = false; 7426 getSelectionHalosEnabled()7427 public boolean getSelectionHalosEnabled() { 7428 return selectionHalosEnabled; 7429 } 7430 setSelectionHalosEnabled(boolean TF)7431 public void setSelectionHalosEnabled(boolean TF) { 7432 if (selectionHalosEnabled == TF) 7433 return; 7434 g.setB("selectionHalos", TF); 7435 shm.loadShape(JC.SHAPE_HALOS); 7436 selectionHalosEnabled = TF; 7437 } 7438 getShowSelectedOnce()7439 public boolean getShowSelectedOnce() { 7440 boolean flag = showSelected; 7441 showSelected = false; 7442 return flag; 7443 } 7444 setStrandCount(int type, int value)7445 private void setStrandCount(int type, int value) { 7446 value = checkIntRange(value, 0, 20); 7447 switch (type) { 7448 case JC.SHAPE_STRANDS: 7449 g.strandCountForStrands = value; 7450 break; 7451 case JC.SHAPE_MESHRIBBON: 7452 g.strandCountForMeshRibbon = value; 7453 break; 7454 default: 7455 g.strandCountForStrands = value; 7456 g.strandCountForMeshRibbon = value; 7457 break; 7458 } 7459 g.setI("strandCount", value); 7460 g.setI("strandCountForStrands", g.strandCountForStrands); 7461 g.setI("strandCountForMeshRibbon", g.strandCountForMeshRibbon); 7462 } 7463 getStrandCount(int type)7464 public int getStrandCount(int type) { 7465 return (type == JC.SHAPE_STRANDS ? g.strandCountForStrands 7466 : g.strandCountForMeshRibbon); 7467 } 7468 setNavigationMode(boolean TF)7469 public void setNavigationMode(boolean TF) { 7470 g.navigationMode = TF; 7471 tm.setNavigationMode(TF); 7472 } 7473 7474 @Override setAutoBond(boolean TF)7475 public void setAutoBond(boolean TF) { 7476 // setBooleanProperties 7477 g.setB("autobond", TF); 7478 g.autoBond = TF; 7479 } 7480 makeConnections(float minDistance, float maxDistance, int order, int connectOperation, BS bsA, BS bsB, BS bsBonds, boolean isBonds, boolean addGroup, float energy)7481 public int[] makeConnections(float minDistance, float maxDistance, int order, 7482 int connectOperation, BS bsA, BS bsB, BS bsBonds, 7483 boolean isBonds, boolean addGroup, 7484 float energy) { 7485 // eval 7486 clearModelDependentObjects(); 7487 // removed in 12.3.2 and 12.2.1; cannot remember why this was important 7488 // we aren't removing atoms, just bonds. So who cares in terms of measurements? 7489 // clearAllMeasurements(); // necessary for serialization (??) 7490 clearMinimization(); 7491 return ms.makeConnections(minDistance, maxDistance, order, connectOperation, 7492 bsA, bsB, bsBonds, isBonds, addGroup, energy); 7493 } 7494 7495 @Override rebond()7496 public void rebond() { 7497 // PreferencesDialog 7498 rebondState(false); 7499 } 7500 rebondState(boolean isStateScript)7501 public void rebondState(boolean isStateScript) { 7502 // Eval CONNECT 7503 clearModelDependentObjects(); 7504 ms.deleteAllBonds(); 7505 boolean isLegacy = isStateScript && g.legacyAutoBonding; 7506 ms.autoBondBs4(null, null, null, null, getMadBond(), isLegacy); 7507 addStateScript((isLegacy 7508 ? "set legacyAutoBonding TRUE;connect;set legacyAutoBonding FALSE;" 7509 : "connect;"), false, true); 7510 } 7511 7512 // /////////////////////////////////////////////////////////////// 7513 // delegated to stateManager 7514 // /////////////////////////////////////////////////////////////// 7515 7516 @Override setPercentVdwAtom(int value)7517 public void setPercentVdwAtom(int value) { 7518 g.setI("percentVdwAtom", value); 7519 g.percentVdwAtom = value; 7520 rd.value = value / 100f; 7521 rd.factorType = EnumType.FACTOR; 7522 rd.vdwType = VDW.AUTO; 7523 shm.setShapeSizeBs(JC.SHAPE_BALLS, 0, rd, null); 7524 } 7525 7526 @Override getMadBond()7527 public short getMadBond() { 7528 return (short) (g.bondRadiusMilliAngstroms * 2); 7529 } 7530 7531 @Override setShowHydrogens(boolean TF)7532 public void setShowHydrogens(boolean TF) { 7533 // PreferencesDialog 7534 // setBooleanProperty 7535 g.setB("showHydrogens", TF); 7536 g.showHydrogens = TF; 7537 } 7538 setShowBbcage(boolean value)7539 public void setShowBbcage(boolean value) { 7540 setObjectMad10(JC.SHAPE_BBCAGE, "boundbox", (short) (value ? -4 : 0)); 7541 g.setB("showBoundBox", value); 7542 } 7543 getShowBbcage()7544 public boolean getShowBbcage() { 7545 return getObjectMad10(StateManager.OBJ_BOUNDBOX) != 0; 7546 } 7547 setShowUnitCell(boolean value)7548 public void setShowUnitCell(boolean value) { 7549 setObjectMad10(JC.SHAPE_UCCAGE, "unitcell", (short) (value ? -2 : 0)); 7550 g.setB("showUnitCell", value); 7551 } 7552 getShowUnitCell()7553 public boolean getShowUnitCell() { 7554 return getObjectMad10(StateManager.OBJ_UNITCELL) != 0; 7555 } 7556 setShowAxes(boolean value)7557 public void setShowAxes(boolean value) { 7558 setObjectMad10(JC.SHAPE_AXES, "axes", (short) (value ? -2 : 0)); 7559 g.setB("showAxes", value); 7560 } 7561 getShowAxes()7562 public boolean getShowAxes() { 7563 return getObjectMad10(StateManager.OBJ_AXIS1) != 0; 7564 } 7565 7566 public boolean frankOn = true; 7567 public boolean noFrankEcho = true; // set when Echo bottom right renders 7568 7569 @Override setFrankOn(boolean TF)7570 public void setFrankOn(boolean TF) { 7571 if (isPreviewOnly) 7572 TF = false; 7573 frankOn = TF; 7574 setObjectMad10(JC.SHAPE_FRANK, "frank", (short) (TF ? 1 : 0)); 7575 } 7576 getShowFrank()7577 public boolean getShowFrank() { 7578 if (isPreviewOnly || isApplet && creatingImage) 7579 return false; 7580 // Java remote signed applet only? 7581 return (isSignedApplet && !isSignedAppletLocal && !isJS || frankOn); 7582 } 7583 7584 @Override setShowMeasurements(boolean TF)7585 public void setShowMeasurements(boolean TF) { 7586 // setbooleanProperty 7587 g.setB("showMeasurements", TF); 7588 g.showMeasurements = TF; 7589 } 7590 setUnits(String units, boolean isDistance)7591 public void setUnits(String units, boolean isDistance) { 7592 // stateManager 7593 // Eval 7594 g.setUnits(units); 7595 if (isDistance) { 7596 g.setUnits(units); 7597 setShapeProperty(JC.SHAPE_MEASURES, "reformatDistances", null); 7598 } else { 7599 7600 } 7601 } 7602 7603 @Override setRasmolDefaults()7604 public void setRasmolDefaults() { 7605 setDefaultsType("RasMol"); 7606 } 7607 7608 @Override setJmolDefaults()7609 public void setJmolDefaults() { 7610 setDefaultsType("Jmol"); 7611 } 7612 setDefaultsType(String type)7613 private void setDefaultsType(String type) { 7614 if (type.equalsIgnoreCase("RasMol")) { 7615 stm.setRasMolDefaults(); 7616 return; 7617 } 7618 if (type.equalsIgnoreCase("PyMOL")) { 7619 stm.setPyMOLDefaults(); 7620 return; 7621 } 7622 stm.setJmolDefaults(); 7623 setIntProperty("bondingVersion", Elements.RAD_COV_IONIC_OB1_100_1); 7624 shm.setShapeSizeBs(JC.SHAPE_BALLS, 0, rd, getAllAtoms()); 7625 } 7626 setAntialias(int tok, boolean TF)7627 private void setAntialias(int tok, boolean TF) { 7628 boolean isChanged = false; 7629 switch (tok) { 7630 case T.antialiasdisplay: 7631 isChanged = (g.antialiasDisplay != TF); 7632 g.antialiasDisplay = TF; 7633 break; 7634 case T.antialiastranslucent: 7635 isChanged = (g.antialiasTranslucent != TF); 7636 g.antialiasTranslucent = TF; 7637 break; 7638 case T.antialiasimages: 7639 g.antialiasImages = TF; 7640 return; 7641 } 7642 if (isChanged) { 7643 resizeImage(0, 0, false, false, true); // for antialiasdisplay 7644 refresh(REFRESH_SYNC_MASK, "Viewer:setAntialias()"); 7645 } 7646 // resizeImage(0, 0, false, false, true); 7647 } 7648 7649 // ////////////////////////////////////////////////////////////// 7650 // temp manager 7651 // ////////////////////////////////////////////////////////////// 7652 allocTempPoints(int size)7653 public P3[] allocTempPoints(int size) { 7654 // rockets cartoons renderer only 7655 return tempArray.allocTempPoints(size); 7656 } 7657 freeTempPoints(P3[] tempPoints)7658 public void freeTempPoints(P3[] tempPoints) { 7659 // rockets, cartoons render only 7660 tempArray.freeTempPoints(tempPoints); 7661 } 7662 allocTempScreens(int size)7663 public P3i[] allocTempScreens(int size) { 7664 // mesh and mps 7665 return tempArray.allocTempScreens(size); 7666 } 7667 freeTempScreens(P3i[] tempScreens)7668 public void freeTempScreens(P3i[] tempScreens) { 7669 tempArray.freeTempScreens(tempScreens); 7670 } 7671 allocTempEnum(int size)7672 public STR[] allocTempEnum(int size) { 7673 // mps renderer 7674 return tempArray.allocTempEnum(size); 7675 } 7676 freeTempEnum(STR[] temp)7677 public void freeTempEnum(STR[] temp) { 7678 tempArray.freeTempEnum(temp); 7679 } 7680 7681 // ////////////////////////////////////////////////////////////// 7682 // font stuff 7683 // ////////////////////////////////////////////////////////////// getFont3D(String fontFace, String fontStyle, float fontSize)7684 public Font getFont3D(String fontFace, String fontStyle, float fontSize) { 7685 return gdata.getFont3DFSS(fontFace, fontStyle, fontSize); 7686 } 7687 7688 // ////////////////////////////////////////////////////////////// 7689 // Access to atom properties for clients 7690 // ////////////////////////////////////////////////////////////// 7691 getAtomGroupQuaternions(BS bsAtoms, int nMax)7692 public Quat[] getAtomGroupQuaternions(BS bsAtoms, int nMax) { 7693 return ms.getAtomGroupQuaternions(bsAtoms, nMax, getQuaternionFrame()); 7694 } 7695 7696 // ////////////////////////////////////////////////////////////// 7697 // stereo support 7698 // ////////////////////////////////////////////////////////////// 7699 setStereoMode(int[] twoColors, STER stereoMode, float degrees)7700 public void setStereoMode(int[] twoColors, STER stereoMode, float degrees) { 7701 setFloatProperty("stereoDegrees", degrees); 7702 setBooleanProperty("greyscaleRendering", stereoMode.isBiColor()); 7703 if (twoColors != null) 7704 tm.setStereoMode2(twoColors); 7705 else 7706 tm.setStereoMode(stereoMode); 7707 } 7708 7709 // ////////////////////////////////////////////////////////////// 7710 // 7711 // ////////////////////////////////////////////////////////////// 7712 7713 // /////////////// getProperty ///////////// 7714 7715 public boolean scriptEditorVisible; 7716 7717 public JmolAppConsoleInterface appConsole; 7718 private JmolScriptEditorInterface scriptEditor; 7719 GenericMenuInterface jmolpopup; 7720 private ModelKitPopup modelkit; 7721 private Map<String, Object> headlessImageParams; 7722 getChimeInfo(int tok)7723 public String getChimeInfo(int tok) { 7724 return getPropertyManager().getChimeInfo(tok, bsA()); 7725 } 7726 getModelFileInfo()7727 public String getModelFileInfo() { 7728 return getPropertyManager().getModelFileInfo(getVisibleFramesBitSet()); 7729 } 7730 getModelFileInfoAll()7731 public String getModelFileInfoAll() { 7732 return getPropertyManager().getModelFileInfo(null); 7733 } 7734 showEditor(String[] file_text)7735 public void showEditor(String[] file_text) { 7736 JmolScriptEditorInterface scriptEditor = (JmolScriptEditorInterface) getProperty( 7737 "DATA_API", "getScriptEditor", Boolean.TRUE); 7738 if (scriptEditor == null) 7739 return; 7740 scriptEditor.show(file_text); 7741 } 7742 7743 JmolPropertyManager pm; 7744 getPropertyManager()7745 private JmolPropertyManager getPropertyManager() { 7746 if (pm == null) 7747 (pm = (JmolPropertyManager) Interface 7748 .getInterface("org.jmol.viewer.PropertyManager", this, "prop")) 7749 .setViewer(this); 7750 return pm; 7751 } 7752 7753 // //////////////////////////////////////////////// 7754 7755 boolean isTainted = true; 7756 setTainted(boolean TF)7757 public void setTainted(boolean TF) { 7758 isTainted = axesAreTainted = (TF && (refreshing || creatingImage)); 7759 } 7760 checkObjectClicked(int x, int y, int modifiers)7761 Map<String, Object> checkObjectClicked(int x, int y, int modifiers) { 7762 return shm.checkObjectClicked(x, y, modifiers, getVisibleFramesBitSet(), 7763 g.drawPicking); 7764 } 7765 checkObjectHovered(int x, int y)7766 public boolean checkObjectHovered(int x, int y) { 7767 return (x >= 0 && shm != null && shm.checkObjectHovered(x, y, 7768 getVisibleFramesBitSet(), getBondsPickable())); 7769 } 7770 checkObjectDragged(int prevX, int prevY, int x, int y, int action)7771 boolean checkObjectDragged(int prevX, int prevY, int x, int y, int action) { 7772 int iShape = 0; 7773 switch (getPickingMode()) { 7774 case ActionManager.PICKING_LABEL: 7775 iShape = JC.SHAPE_LABELS; 7776 break; 7777 case ActionManager.PICKING_DRAW: 7778 iShape = JC.SHAPE_DRAW; 7779 break; 7780 } 7781 if (shm.checkObjectDragged(prevX, prevY, x, y, action, 7782 getVisibleFramesBitSet(), iShape)) { 7783 refresh(REFRESH_REPAINT, "checkObjectDragged"); 7784 if (iShape == JC.SHAPE_DRAW) 7785 scriptEcho((String) getShapeProperty(JC.SHAPE_DRAW, "command")); 7786 return true; 7787 } 7788 return false; 7789 } 7790 rotateAxisAngleAtCenter(JmolScriptEvaluator eval, P3 rotCenter, V3 rotAxis, float degreesPerSecond, float endDegrees, boolean isSpin, BS bsSelected)7791 public boolean rotateAxisAngleAtCenter(JmolScriptEvaluator eval, P3 rotCenter, 7792 V3 rotAxis, float degreesPerSecond, 7793 float endDegrees, boolean isSpin, 7794 BS bsSelected) { 7795 // Eval: rotate FIXED 7796 boolean isOK = tm.rotateAxisAngleAtCenter(eval, rotCenter, rotAxis, 7797 degreesPerSecond, endDegrees, isSpin, bsSelected); 7798 if (isOK) 7799 setSync(); 7800 return isOK; 7801 } 7802 rotateAboutPointsInternal(JmolScriptEvaluator eval, P3 point1, P3 point2, float degreesPerSecond, float endDegrees, boolean isSpin, BS bsSelected, V3 translation, Lst<P3> finalPoints, float[] dihedralList, M4 m4)7803 public boolean rotateAboutPointsInternal(JmolScriptEvaluator eval, P3 point1, 7804 P3 point2, float degreesPerSecond, 7805 float endDegrees, boolean isSpin, 7806 BS bsSelected, V3 translation, 7807 Lst<P3> finalPoints, 7808 float[] dihedralList, M4 m4) { 7809 // Eval: rotate INTERNAL 7810 7811 if (eval == null) 7812 eval = this.eval; 7813 7814 if (headless) { 7815 if (isSpin && endDegrees == Float.MAX_VALUE) 7816 return false; 7817 isSpin = false; 7818 } 7819 7820 boolean isOK = tm.rotateAboutPointsInternal(eval, point1, point2, 7821 degreesPerSecond, endDegrees, false, isSpin, bsSelected, false, 7822 translation, finalPoints, dihedralList, m4); 7823 if (isOK) 7824 setSync(); 7825 return isOK; 7826 } 7827 startSpinningAxis(T3 pt1, T3 pt2, boolean isClockwise)7828 public void startSpinningAxis(T3 pt1, T3 pt2, boolean isClockwise) { 7829 // Draw.checkObjectClicked ** could be difficult 7830 // from draw object click 7831 if (tm.spinOn || tm.navOn) { 7832 tm.setSpinOff(); 7833 tm.setNavOn(false); 7834 return; 7835 } 7836 tm.rotateAboutPointsInternal(null, pt1, pt2, g.pickingSpinRate, 7837 Float.MAX_VALUE, isClockwise, true, null, false, null, null, null, 7838 null); 7839 } 7840 getModelDipole()7841 public V3 getModelDipole() { 7842 return ms.getModelDipole(am.cmi); 7843 } 7844 calculateMolecularDipole(BS bsAtoms)7845 public V3 calculateMolecularDipole(BS bsAtoms) throws Exception { 7846 try { 7847 return ms.calculateMolecularDipole(am.cmi, bsAtoms); 7848 } catch (JmolAsyncException e) { 7849 if (eval != null) 7850 eval.loadFileResourceAsync(e.getFileName()); 7851 return null; 7852 } 7853 } 7854 setDefaultLattice(P3 p)7855 public void setDefaultLattice(P3 p) { 7856 // Eval -- handled separately 7857 if (!Float.isNaN(p.x + p.y + p.z)) 7858 g.ptDefaultLattice.setT(p); 7859 g.setO("defaultLattice", Escape.eP(p)); 7860 } 7861 getDefaultLattice()7862 public P3 getDefaultLattice() { 7863 return g.ptDefaultLattice; 7864 } 7865 7866 /** 7867 * 7868 * V3000, SDF, JSON, CD, XYZ, XYZVIB, XYZRN, CML, PDB, PQR 7869 * 7870 * @param atomExpression 7871 * @param doTransform 7872 * @param isModelKit 7873 * @param type 7874 * @return full file data 7875 * 7876 */ getModelExtract(Object atomExpression, boolean doTransform, boolean isModelKit, String type)7877 public String getModelExtract(Object atomExpression, boolean doTransform, 7878 boolean isModelKit, String type) { 7879 return getPropertyManager().getModelExtract(getAtomBitSet(atomExpression), 7880 doTransform, isModelKit, type, false); 7881 } 7882 7883 @Override getData(String atomExpression, String type)7884 public String getData(String atomExpression, String type) { 7885 // from GaussianDialog 7886 return getModelFileData(atomExpression, type, true); 7887 } 7888 7889 /** 7890 * @param atomExpression 7891 * -- will be wrapped in { } and evaluated 7892 * @param type 7893 * -- lower case means "atom data only; UPPERCASE returns full file 7894 * data 7895 * @param allTrajectories 7896 * @return full or atom-only data formatted as specified 7897 */ getModelFileData(String atomExpression, String type, boolean allTrajectories)7898 public String getModelFileData(String atomExpression, String type, 7899 boolean allTrajectories) { 7900 return getPropertyManager().getAtomData(atomExpression, type, 7901 allTrajectories); 7902 } 7903 getModelCml(BS bs, int nAtomsMax, boolean addBonds, boolean doTransform)7904 public String getModelCml(BS bs, int nAtomsMax, boolean addBonds, 7905 boolean doTransform) { 7906 return getPropertyManager().getModelCml(bs, nAtomsMax, addBonds, 7907 doTransform, false); 7908 } 7909 getPdbAtomData(BS bs, OC out, boolean asPQR, boolean doTransform)7910 public String getPdbAtomData(BS bs, OC out, boolean asPQR, 7911 boolean doTransform) { 7912 return getPropertyManager().getPdbAtomData(bs == null ? bsA() : bs, out, 7913 asPQR, doTransform, false); 7914 } 7915 isJmolDataFrame()7916 public boolean isJmolDataFrame() { 7917 return ms.isJmolDataFrameForModel(am.cmi); 7918 } 7919 setFrameTitle(int modelIndex, String title)7920 public void setFrameTitle(int modelIndex, String title) { 7921 ms.setFrameTitle(BSUtil.newAndSetBit(modelIndex), title); 7922 } 7923 setFrameTitleObj(Object title)7924 public void setFrameTitleObj(Object title) { 7925 shm.loadShape(JC.SHAPE_ECHO); 7926 ms.setFrameTitle(getVisibleFramesBitSet(), title); 7927 } 7928 getFrameTitle()7929 public String getFrameTitle() { 7930 return ms.getFrameTitle(am.cmi); 7931 } 7932 setAtomProperty(BS bs, int tok, int iValue, float fValue, String sValue, float[] values, String[] list)7933 public void setAtomProperty(BS bs, int tok, int iValue, float fValue, 7934 String sValue, float[] values, String[] list) { 7935 if (tok == T.vanderwaals) 7936 shm.deleteVdwDependentShapes(bs); 7937 clearMinimization(); 7938 ms.setAtomProperty(bs, tok, iValue, fValue, sValue, values, list); 7939 switch (tok) { 7940 case T.atomx: 7941 case T.atomy: 7942 case T.atomz: 7943 case T.fracx: 7944 case T.fracy: 7945 case T.fracz: 7946 case T.unitx: 7947 case T.unity: 7948 case T.unitz: 7949 case T.element: 7950 refreshMeasures(true); 7951 } 7952 } 7953 checkCoordinatesChanged()7954 public void checkCoordinatesChanged() { 7955 // note -- use of save/restore coordinates cannot 7956 // track connected objects 7957 ms.recalculatePositionDependentQuantities(null, null); 7958 refreshMeasures(true); 7959 } 7960 setAtomCoords(BS bs, int tokType, Object xyzValues)7961 public void setAtomCoords(BS bs, int tokType, Object xyzValues) { 7962 if (bs.isEmpty()) 7963 return; 7964 ms.setAtomCoords(bs, tokType, xyzValues); 7965 checkMinimization(); 7966 sm.setStatusAtomMoved(bs); 7967 } 7968 setAtomCoordsRelative(T3 offset, BS bs)7969 public void setAtomCoordsRelative(T3 offset, BS bs) { 7970 // Eval 7971 if (bs == null) 7972 bs = bsA(); 7973 if (bs.isEmpty()) 7974 return; 7975 ms.setAtomCoordsRelative(offset, bs); 7976 checkMinimization(); 7977 sm.setStatusAtomMoved(bs); 7978 } 7979 invertAtomCoordPt(P3 pt, BS bs)7980 public void invertAtomCoordPt(P3 pt, BS bs) { 7981 // Eval 7982 ms.invertSelected(pt, null, -1, bs); 7983 checkMinimization(); 7984 sm.setStatusAtomMoved(bs); 7985 } 7986 invertAtomCoordPlane(P4 plane, BS bs)7987 public void invertAtomCoordPlane(P4 plane, BS bs) { 7988 ms.invertSelected(null, plane, -1, bs); 7989 checkMinimization(); 7990 sm.setStatusAtomMoved(bs); 7991 } 7992 invertRingAt(int atomIndex, boolean isClick)7993 public void invertRingAt(int atomIndex, boolean isClick) { 7994 // [r50 here just sets the max ring size to 50 7995 BS bs = getAtomBitSet( 7996 "connected(atomIndex=" + atomIndex + ") and !within(SMARTS,'[r50,R]')"); 7997 int nb = bs.cardinality(); 7998 switch (nb) { 7999 case 0: 8000 case 1: 8001 // not enough non-ring atoms 8002 return; 8003 case 2: 8004 break; 8005 case 3: 8006 case 4: 8007 // three or four are not in a ring. So let's find the shortest two 8008 // branches and invert them. 8009 int[] lengths = new int[nb]; 8010 int[] points = new int[nb]; 8011 int ni = 0; 8012 for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1), ni++) { 8013 lengths[ni] = getBranchBitSet(i, atomIndex, true).cardinality(); 8014 points[ni] = i; 8015 } 8016 for (int j = 0; j < nb - 2; j++) { 8017 int max = Integer.MIN_VALUE; 8018 int imax = 0; 8019 for (int i = 0; i < nb; i++) 8020 if (lengths[i] >= max && bs.get(points[i])) { 8021 imax = points[i]; 8022 max = lengths[i]; 8023 } 8024 bs.clear(imax); 8025 } 8026 } 8027 if (isClick) 8028 undoMoveActionClear(atomIndex, AtomCollection.TAINT_COORD, true); 8029 invertSelected(null, null, atomIndex, bs); 8030 if (isClick) 8031 setStatusAtomPicked(atomIndex, "inverted: " + Escape.eBS(bs), null, 8032 false); 8033 } 8034 invertSelected(P3 pt, P4 plane, int iAtom, BS bsAtoms)8035 public void invertSelected(P3 pt, P4 plane, int iAtom, BS bsAtoms) { 8036 // Eval 8037 if (bsAtoms == null) 8038 bsAtoms = bsA(); 8039 if (bsAtoms.cardinality() == 0) 8040 return; 8041 ms.invertSelected(pt, plane, iAtom, bsAtoms); 8042 checkMinimization(); 8043 sm.setStatusAtomMoved(bsAtoms); 8044 } 8045 moveAtoms(M4 m4, M3 mNew, M3 rotation, V3 translation, P3 center, boolean isInternal, BS bsAtoms, boolean translationOnly)8046 public void moveAtoms(M4 m4, M3 mNew, M3 rotation, V3 translation, P3 center, 8047 boolean isInternal, BS bsAtoms, 8048 boolean translationOnly) { 8049 // from TransformManager exclusively 8050 if (bsAtoms.isEmpty()) 8051 return; 8052 ms.moveAtoms(m4, mNew, rotation, translation, bsAtoms, center, isInternal, 8053 translationOnly); 8054 checkMinimization(); 8055 sm.setStatusAtomMoved(bsAtoms); 8056 } 8057 8058 private boolean movingSelected; 8059 private boolean showSelected; 8060 moveSelected(int deltaX, int deltaY, int deltaZ, int x, int y, BS bsSelected, boolean isTranslation, boolean asAtoms, int modifiers)8061 public void moveSelected(int deltaX, int deltaY, int deltaZ, int x, int y, 8062 BS bsSelected, boolean isTranslation, 8063 boolean asAtoms, int modifiers) { 8064 // called by actionManager 8065 // cannot synchronize this -- it's from the mouse and the event queue 8066 if (deltaZ == 0) 8067 return; 8068 if (x == Integer.MIN_VALUE) 8069 setModelKitRotateBondIndex(Integer.MIN_VALUE); 8070 if (isJmolDataFrame()) 8071 return; 8072 if (deltaX == Integer.MIN_VALUE) { 8073 showSelected = true; 8074 movableBitSet = setMovableBitSet(null, !asAtoms); 8075 shm.loadShape(JC.SHAPE_HALOS); 8076 refresh(REFRESH_REPAINT_NO_MOTION_ONLY, "moveSelected"); 8077 return; 8078 } 8079 if (deltaX == Integer.MAX_VALUE) { 8080 if (!showSelected) 8081 return; 8082 showSelected = false; 8083 movableBitSet = null; 8084 refresh(REFRESH_REPAINT_NO_MOTION_ONLY, "moveSelected"); 8085 return; 8086 } 8087 if (movingSelected) 8088 return; 8089 movingSelected = true; 8090 stopMinimization(); 8091 // note this does not sync with applets 8092 if (x != Integer.MIN_VALUE && modelkit != null 8093 && modelkit.getProperty("rotateBondIndex") != null) { 8094 modelkit.actionRotateBond(deltaX, deltaY, x, y, 8095 (modifiers & Event.VK_SHIFT) != 0); 8096 } else { 8097 bsSelected = setMovableBitSet(bsSelected, !asAtoms); 8098 if (!bsSelected.isEmpty()) { 8099 if (isTranslation) { 8100 P3 ptCenter = ms.getAtomSetCenter(bsSelected); 8101 tm.finalizeTransformParameters(); 8102 float f = (g.antialiasDisplay ? 2 : 1); 8103 P3i ptScreen = tm.transformPt(ptCenter); 8104 P3 ptScreenNew; 8105 if (deltaZ != Integer.MIN_VALUE) 8106 ptScreenNew = P3.new3(ptScreen.x, ptScreen.y, 8107 ptScreen.z + deltaZ + 0.5f); 8108 else 8109 ptScreenNew = P3.new3(ptScreen.x + deltaX * f + 0.5f, 8110 ptScreen.y + deltaY * f + 0.5f, ptScreen.z); 8111 P3 ptNew = new P3(); 8112 tm.unTransformPoint(ptScreenNew, ptNew); 8113 // script("draw ID 'pt" + Math.random() + "' " + Escape.escape(ptNew)); 8114 ptNew.sub(ptCenter); 8115 setAtomCoordsRelative(ptNew, bsSelected); 8116 } else { 8117 tm.rotateXYBy(deltaX, deltaY, bsSelected); 8118 } 8119 } 8120 } 8121 refresh(REFRESH_SYNC, ""); // should be syncing here 8122 movingSelected = false; 8123 } 8124 8125 /** 8126 * from Sticks 8127 * 8128 * @param index 8129 * @param closestAtomIndex 8130 * @param x 8131 * @param y 8132 */ highlightBond(int index, int closestAtomIndex, int x, int y)8133 public void highlightBond(int index, int closestAtomIndex, int x, int y) {//, String msg) { 8134 if (!hoverEnabled) 8135 return; 8136 BS bs = null; 8137 if (index >= 0) { 8138 Bond b = ms.bo[index]; 8139 int i = b.atom2.i; 8140 if (!ms.isAtomInLastModel(i)) 8141 return; 8142 bs = BSUtil.newAndSetBit(i); 8143 bs.set(b.atom1.i); 8144 } 8145 highlight(bs); 8146 setModelkitProperty("bondIndex", Integer.valueOf(index)); 8147 setModelkitProperty("screenXY", new int[] { x, y }); 8148 String text = (String) setModelkitProperty("hoverLabel", 8149 Integer.valueOf(-2 - index)); 8150 if (text != null) 8151 hoverOnPt(x, y, text, null, null); 8152 // hoverOn(closestAtomIndex, false); 8153 refresh(REFRESH_SYNC_MASK, "highlightBond"); 8154 } 8155 8156 public int atomHighlighted = -1; 8157 highlight(BS bs)8158 public void highlight(BS bs) { 8159 atomHighlighted = (bs != null && bs.cardinality() == 1 ? bs.nextSetBit(0) 8160 : -1); 8161 8162 if (bs == null) { 8163 setCursor(GenericPlatform.CURSOR_DEFAULT); 8164 } else { 8165 shm.loadShape(JC.SHAPE_HALOS); 8166 setCursor(GenericPlatform.CURSOR_HAND); 8167 } 8168 setModelkitProperty("highlight", bs); 8169 setShapeProperty(JC.SHAPE_HALOS, "highlight", bs); 8170 } 8171 refreshMeasures(boolean andStopMinimization)8172 public void refreshMeasures(boolean andStopMinimization) { 8173 setShapeProperty(JC.SHAPE_MEASURES, "refresh", null); 8174 if (andStopMinimization) 8175 stopMinimization(); 8176 } 8177 8178 /** 8179 * fills an array with data -- if nX < 0 and this would involve JavaScript, 8180 * then this reads a full set of Double[][] in one function call. Otherwise it 8181 * reads the values using individual function calls, which each return Double. 8182 * 8183 * If the functionName begins with "file:" then data are read from a file 8184 * specified after the colon. The sign of nX is not relevant in that case. The 8185 * file may contain mixed numeric and non-numeric values; the non-numeric 8186 * values will be skipped by Parser.parseFloatArray 8187 * 8188 * @param functionName 8189 * @param nX 8190 * @param nY 8191 * @return nX by nY array of floating values 8192 */ functionXY(String functionName, int nX, int nY)8193 public float[][] functionXY(String functionName, int nX, int nY) { 8194 String data = null; 8195 if (functionName.indexOf("file:") == 0) 8196 data = getFileAsString3(functionName.substring(5), false, null); 8197 else if (functionName.indexOf("data2d_") != 0) 8198 return sm.functionXY(functionName, nX, nY); 8199 nX = Math.abs(nX); 8200 nY = Math.abs(nY); 8201 float[][] fdata; 8202 if (data == null) { 8203 fdata = (float[][]) getDataObj(functionName, null, 8204 JmolDataManager.DATA_TYPE_AFF); 8205 if (fdata != null) 8206 return fdata; 8207 data = ""; 8208 } 8209 fdata = new float[nX][nY]; 8210 float[] f = new float[nX * nY]; 8211 Parser.parseStringInfestedFloatArray(data, null, f); 8212 for (int i = 0, n = 0; i < nX; i++) 8213 for (int j = 0; j < nY; j++) 8214 fdata[i][j] = f[n++]; 8215 return fdata; 8216 } 8217 functionXYZ(String functionName, int nX, int nY, int nZ)8218 public float[][][] functionXYZ(String functionName, int nX, int nY, int nZ) { 8219 String data = null; 8220 if (functionName.indexOf("file:") == 0) 8221 data = getFileAsString3(functionName.substring(5), false, null); 8222 else if (functionName.indexOf("data3d_") != 0) 8223 return sm.functionXYZ(functionName, nX, nY, nZ); 8224 nX = Math.abs(nX); 8225 nY = Math.abs(nY); 8226 nZ = Math.abs(nZ); 8227 float[][][] xyzdata; 8228 if (data == null) { 8229 xyzdata = (float[][][]) getDataObj(functionName, null, 8230 JmolDataManager.DATA_TYPE_AFF); 8231 if (xyzdata != null) 8232 return xyzdata; 8233 data = ""; 8234 } 8235 xyzdata = new float[nX][nY][nZ]; 8236 float[] f = new float[nX * nY * nZ]; 8237 Parser.parseStringInfestedFloatArray(data, null, f); 8238 for (int i = 0, n = 0; i < nX; i++) 8239 for (int j = 0; j < nY; j++) 8240 for (int k = 0; k < nZ; k++) 8241 xyzdata[i][j][k] = f[n++]; 8242 return xyzdata; 8243 } 8244 8245 @Override extractMolData(String what)8246 public String extractMolData(String what) { 8247 if (what == null) { 8248 int i = am.cmi; 8249 if (i < 0 || ms.ac == 0) 8250 return null; 8251 what = getModelNumberDotted(i); 8252 } 8253 return getModelExtract(what, true, false, "V2000"); 8254 } 8255 8256 /** 8257 * 8258 * @param type 8259 * C13 or H1 8260 * @return null 8261 */ getNMRPredict(String type)8262 public String getNMRPredict(String type) { 8263 type = type.toUpperCase(); 8264 if (type.equals("H") || type.equals("1H") || type.equals("")) 8265 type = "H1"; 8266 else if (type.equals("C") || type.equals("13C")) 8267 type = "C13"; 8268 if (!type.equals("NONE")) { 8269 if (!type.equals("C13") && !type.equals("H1")) 8270 return "Type must be H1 or C13"; 8271 String molFile = getModelExtract("selected", true, false, "V2000"); 8272 int pt = molFile.indexOf("\n"); 8273 if (pt < 0) 8274 return null; 8275 molFile = "Jmol " + version_date + molFile.substring(pt); 8276 if (isApplet) { 8277 //TODO -- can do this if connected 8278 showUrl(g.nmrUrlFormat + molFile); 8279 return "opening " + g.nmrUrlFormat; 8280 } 8281 } 8282 syncScript("true", "*", 0); 8283 syncScript(type + "Simulate:", ".", 0); 8284 return "sending request to JSpecView"; 8285 } 8286 getHelp(String what)8287 public void getHelp(String what) { 8288 if (g.helpPath.indexOf("?") < 0) { 8289 if (what.length() > 0 && what.indexOf("?") != 0) 8290 what = "?search=" + PT.rep(what, " ", "%20"); 8291 what += (what.length() == 0 ? "?ver=" : "&ver=") + JC.majorVersion; 8292 } else { 8293 what = "&" + what; 8294 } 8295 showUrl(g.helpPath + what); 8296 } 8297 getChemicalInfo(String smiles, String info, BS bsAtoms)8298 public String getChemicalInfo(String smiles, String info, BS bsAtoms) { 8299 info = info.toLowerCase(); 8300 char type = '/'; 8301 switch (";inchi;inchikey;stdinchi;stdinchikey;name;image;drawing;names;" 8302 .indexOf(";" + info + ";")) { 8303 // 0 6 15 24 36 41 47 55 8304 // 0 1 2 3 4 5 8305 // 0123456789012345678901234567890123456789012345678901234567890 8306 case 0: // inchi 8307 type = 'I'; 8308 break; 8309 case 6: // inchikey 8310 type = 'K'; 8311 break; 8312 case 15: // stdinchi 8313 type = 'T'; 8314 break; 8315 case 24: // stdinchikey 8316 type = 'S'; 8317 break; 8318 case 36: // name 8319 type = 'M'; 8320 break; 8321 case 41: // image 8322 case 47: // drawing 8323 type = '2'; 8324 break; 8325 case 55: // names 8326 type = 'N'; 8327 break; 8328 } 8329 String s = (String) setLoadFormat("_" + smiles, type, false); 8330 if (type == '2') { 8331 fm.loadImage(s, "\1" + smiles, false); 8332 return s; 8333 } 8334 if (type == '/') { 8335 if (PT.isOneOf(info, JC.CACTUS_FILE_TYPES)) 8336 s += "file?format=" + info; 8337 else 8338 s += PT.rep(info, " ", "%20"); 8339 } 8340 s = getFileAsString4(s, -1, false, false, false, "file"); 8341 if (type == 'M' && s.indexOf("\n") > 0) 8342 s = s.substring(0, s.indexOf("\n")); 8343 else if (info.equals("jme")) 8344 s = getPropertyManager().fixJMEFormalCharges(bsAtoms, s); 8345 return s; 8346 } 8347 8348 // /////////////////////////////////////////////////////////////// 8349 // delegated to stateManager 8350 // /////////////////////////////////////////////////////////////// 8351 8352 /* 8353 * Moved from the consoles to vwr, since this could be of general interest, 8354 * it's more a property of Eval/Viewer, and the consoles are really just a 8355 * mechanism for getting user input and sending results, not saving a history 8356 * of it all. Ultimately I hope to integrate the mouse picking and possibly 8357 * periodic updates of position into this history to get a full history. We'll 8358 * see! BH 9/2006 8359 */ 8360 8361 /** 8362 * Adds one or more commands to the command history 8363 * 8364 * @param command 8365 * the command to add 8366 */ addCommand(String command)8367 public void addCommand(String command) { 8368 if (autoExit || !haveDisplay || !getPreserveState()) 8369 return; 8370 commandHistory.addCommand(PT.replaceAllCharacters(command, "\r\n\t", " ")); 8371 } 8372 pushState()8373 public void pushState() { 8374 if (autoExit || !haveDisplay || !getPreserveState()) 8375 return; 8376 commandHistory.pushState(getStateInfo()); 8377 } 8378 popState()8379 public void popState() { 8380 if (autoExit || !haveDisplay || !getPreserveState()) 8381 return; 8382 String state = commandHistory.popState(); 8383 if (state != null) 8384 evalStringQuiet(state); 8385 } 8386 8387 /** 8388 * Removes one command from the command history 8389 * 8390 * @return command removed 8391 */ removeCommand()8392 public String removeCommand() { 8393 return commandHistory.removeCommand(); 8394 } 8395 8396 /** 8397 * Options include: ; all n == Integer.MAX_VALUE ; n prev n >= 1 ; next n == 8398 * -1 ; set max to -2 - n n <= -3 ; just clear n == -2 ; clear and turn off; 8399 * return "" n == 0 ; clear and turn on; return "" n == Integer.MIN_VALUE; 8400 * 8401 * @param howFarBack 8402 * number of lines (-1 for next line) 8403 * @return one or more lines of command history 8404 */ 8405 @Override getSetHistory(int howFarBack)8406 public String getSetHistory(int howFarBack) { 8407 return commandHistory.getSetHistory(howFarBack); 8408 } 8409 historyFind(String cmd, int dir)8410 public String historyFind(String cmd, int dir) { 8411 return commandHistory.find(cmd, dir); 8412 } 8413 setHistory(String fileName)8414 public void setHistory(String fileName) { 8415 commandHistory.getSetHistory(Integer.MIN_VALUE); 8416 commandHistory 8417 .addCommand(getFileAsString4(fileName, -1, false, false, true, null)); 8418 } 8419 8420 // /////////////////////////////////////////////////////////////// 8421 // image and file export 8422 // /////////////////////////////////////////////////////////////// 8423 getOutputChannel(String localName, String[] fullPath)8424 public OC getOutputChannel(String localName, String[] fullPath) { 8425 return getOutputManager().getOutputChannel(localName, fullPath); 8426 } 8427 8428 @Override writeTextFile(String fileName, String data)8429 public String writeTextFile(String fileName, String data) { 8430 Map<String, Object> params = new Hashtable<String, Object>(); 8431 params.put("fileName", fileName); 8432 params.put("type", "txt"); 8433 params.put("text", data); 8434 return outputToFile(params); 8435 } 8436 8437 /** 8438 * 8439 * @param text 8440 * null here clips image; String pastes text 8441 * 8442 * @return "OK image to clipboard: [width] * [height] or "OK text to 8443 * clipboard: [length] 8444 */ 8445 @Override clipImageOrPasteText(String text)8446 public String clipImageOrPasteText(String text) { 8447 if (!haveAccess(ACCESS.ALL)) 8448 return "no"; 8449 return getOutputManager().clipImageOrPasteText(text); 8450 } 8451 8452 @Override getClipboardText()8453 public String getClipboardText() { 8454 if (!haveAccess(ACCESS.ALL)) 8455 return "no"; 8456 try { 8457 return getOutputManager().getClipboardText(); 8458 } catch (Error er) { 8459 // unsigned applet will not have this interface 8460 return GT.$("clipboard is not accessible -- use signed applet"); 8461 } 8462 } 8463 8464 public boolean creatingImage; 8465 8466 /** 8467 * 8468 * from eval write command only includes option to write set of files 8469 * 8470 * @param params 8471 * @return message starting with "OK" or an error message 8472 */ processWriteOrCapture(Map<String, Object> params)8473 public String processWriteOrCapture(Map<String, Object> params) { 8474 return getOutputManager().processWriteOrCapture(params); 8475 } 8476 createZip(String fileName, String type, Map<String, Object> params)8477 public Object createZip(String fileName, String type, 8478 Map<String, Object> params) { 8479 String state = getStateInfo(); 8480 Object data = params.get("data"); 8481 if (fileName != null) 8482 params.put("fileName", fileName); 8483 params.put("type", type); 8484 params.put("text", state); 8485 if (data instanceof String[]) 8486 params.put("scripts", data); 8487 else if (data instanceof Lst) 8488 params.put("imageData", data); 8489 return getOutputManager().outputToFile(params); 8490 } 8491 8492 @Override outputToFile(Map<String, Object> params)8493 public String outputToFile(Map<String, Object> params) { 8494 return getOutputManager().outputToFile(params); 8495 } 8496 setSyncTarget(int mode, boolean TF)8497 private void setSyncTarget(int mode, boolean TF) { 8498 switch (mode) { 8499 case 0: 8500 sm.syncingMouse = TF; 8501 break; 8502 case 1: 8503 sm.syncingScripts = TF; 8504 break; 8505 case 2: 8506 sm.syncSend(TF ? SYNC_GRAPHICS_MESSAGE : SYNC_NO_GRAPHICS_MESSAGE, "*", 8507 0); 8508 if (Float.isNaN(tm.stereoDegrees)) 8509 setFloatProperty("stereoDegrees", 8510 TransformManager.DEFAULT_STEREO_DEGREES); 8511 if (TF) { 8512 setBooleanProperty("_syncMouse", false); 8513 setBooleanProperty("_syncScript", false); 8514 } 8515 return; 8516 } 8517 // if turning both off, sync the orientation now 8518 if (!sm.syncingScripts && !sm.syncingMouse) 8519 setSync(); 8520 } 8521 8522 public final static String SYNC_GRAPHICS_MESSAGE = "GET_GRAPHICS"; 8523 public final static String SYNC_NO_GRAPHICS_MESSAGE = "SET_GRAPHICS_OFF"; 8524 8525 @Override syncScript(String script, String applet, int port)8526 public void syncScript(String script, String applet, int port) { 8527 sm.syncScript(script, applet, port); 8528 } 8529 8530 @Override getModelIndexFromId(String id)8531 public int getModelIndexFromId(String id) { 8532 // from JSpecView peak pick and model "ID" 8533 return ms.getModelIndexFromId(id); 8534 } 8535 setSyncDriver(int mode)8536 public void setSyncDriver(int mode) { 8537 sm.setSyncDriver(mode); 8538 } 8539 setProteinType(STR type, BS bs)8540 public void setProteinType(STR type, BS bs) { 8541 ms.setProteinType(bs == null ? bsA() : bs, type); 8542 } 8543 getVanderwaalsMar(int i)8544 public int getVanderwaalsMar(int i) { 8545 return (defaultVdw == VDW.USER ? userVdwMars[i] 8546 : Elements.getVanderwaalsMar(i, defaultVdw)); 8547 } 8548 getVanderwaalsMarType(int atomicAndIsotopeNumber, VDW type)8549 public int getVanderwaalsMarType(int atomicAndIsotopeNumber, VDW type) { 8550 if (type == null) 8551 type = defaultVdw; 8552 else 8553 switch (type) { 8554 case AUTO: 8555 case AUTO_BABEL: 8556 case AUTO_JMOL: 8557 case AUTO_RASMOL: 8558 if (defaultVdw != VDW.AUTO) 8559 type = defaultVdw; 8560 break; 8561 default: 8562 break; 8563 } 8564 if (type == VDW.USER && bsUserVdws == null) 8565 type = VDW.JMOL; 8566 return (type == VDW.USER ? userVdwMars[atomicAndIsotopeNumber & 127] 8567 : Elements.getVanderwaalsMar(atomicAndIsotopeNumber, type)); 8568 } 8569 setVdwStr(String name)8570 void setVdwStr(String name) { 8571 VDW type = VDW.getVdwType(name); 8572 if (type == null) 8573 type = VDW.AUTO; 8574 // only allowed types here are VDW_JMOL, VDW_BABEL, VDW_RASMOL, VDW_USER, VDW_AUTO 8575 switch (type) { 8576 case JMOL: 8577 case BABEL: 8578 case RASMOL: 8579 case AUTO: 8580 case USER: 8581 break; 8582 default: 8583 type = VDW.JMOL; 8584 } 8585 if (type != defaultVdw && type == VDW.USER && bsUserVdws == null) 8586 setUserVdw(defaultVdw); 8587 defaultVdw = type; 8588 g.setO("defaultVDW", type.getVdwLabel()); 8589 } 8590 8591 BS bsUserVdws; 8592 float[] userVdws; 8593 int[] userVdwMars; 8594 setUserVdw(VDW mode)8595 void setUserVdw(VDW mode) { 8596 userVdwMars = new int[Elements.elementNumberMax]; 8597 userVdws = new float[Elements.elementNumberMax]; 8598 bsUserVdws = new BS(); 8599 if (mode == VDW.USER) 8600 mode = VDW.JMOL; 8601 for (int i = 1; i < Elements.elementNumberMax; i++) { 8602 userVdwMars[i] = Elements.getVanderwaalsMar(i, mode); 8603 userVdws[i] = userVdwMars[i] / 1000f; 8604 } 8605 } 8606 getDefaultVdwNameOrData(int mode, VDW type, BS bs)8607 public String getDefaultVdwNameOrData(int mode, VDW type, BS bs) { 8608 // called by getDataState and via Viewer: Eval.calculate, 8609 // Eval.show, StateManager.getLoadState, Viewer.setDefaultVdw 8610 switch (mode) { 8611 case Integer.MIN_VALUE: 8612 // iMode Integer.MIN_VALUE -- just the name 8613 return defaultVdw.getVdwLabel(); 8614 case Integer.MAX_VALUE: 8615 // iMode = Integer.MAX_VALUE -- user, only selected 8616 if ((bs = bsUserVdws) == null) 8617 return ""; 8618 type = VDW.USER; 8619 break; 8620 } 8621 if (type == null || type == VDW.AUTO) 8622 type = defaultVdw; 8623 if (type == VDW.USER && bsUserVdws == null) 8624 setUserVdw(defaultVdw); 8625 8626 return getDataManager().getDefaultVdwNameOrData(type, bs); 8627 } 8628 deleteAtoms(BS bsAtoms, boolean fullModels)8629 public int deleteAtoms(BS bsAtoms, boolean fullModels) { 8630 int atomIndex = (bsAtoms == null ? -1 : bsAtoms.nextSetBit(0)); 8631 if (atomIndex < 0) 8632 return 0; 8633 clearModelDependentObjects(); 8634 Atom a = ms.at[atomIndex]; 8635 if (a == null) 8636 return 0; 8637 int mi = a.mi; 8638 if (!fullModels) { 8639 sm.modifySend(atomIndex, a.mi, 4, 8640 "deleting atom " + a.getAtomName()); 8641 ms.deleteAtoms(bsAtoms); 8642 int n = slm.deleteAtoms(bsAtoms); 8643 setTainted(true); 8644 sm.modifySend(atomIndex, mi, -4, "OK"); 8645 return n; 8646 } 8647 return deleteModels(mi, bsAtoms); 8648 } 8649 8650 /** 8651 * called by ZAP {atomExpression} when atoms are present or the command is 8652 * specific for a model, such as ZAP 2.1 8653 * 8654 * @param modelIndex 8655 * @param bsAtoms 8656 * @return number of atoms deleted 8657 */ deleteModels(int modelIndex, BS bsAtoms)8658 public int deleteModels(int modelIndex, BS bsAtoms) { 8659 clearModelDependentObjects(); 8660 // fileManager.addLoadScript("zap " + Escape.escape(bs)); 8661 sm.modifySend(-1, modelIndex, 5, 8662 "deleting model " + getModelNumberDotted(modelIndex)); 8663 int currentModel = am.cmi; 8664 setCurrentModelIndexClear(0, false); 8665 am.setAnimationOn(false); 8666 BS bsD0 = BSUtil.copy(slm.bsDeleted); 8667 BS bsModels = (bsAtoms == null ? BSUtil.newAndSetBit(modelIndex) 8668 : ms.getModelBS(bsAtoms, false)); 8669 BS bsDeleted = ms.deleteModels(bsModels); 8670 if (bsDeleted == null) { 8671 setCurrentModelIndexClear(currentModel, false); 8672 return 0; 8673 } 8674 slm.processDeletedModelAtoms(bsDeleted); 8675 if (eval != null) 8676 eval.deleteAtomsInVariables(bsDeleted); 8677 setAnimationRange(0, 0); 8678 clearRepaintManager(-1); 8679 am.clear(); 8680 am.initializePointers(1); 8681 setCurrentModelIndexClear(ms.mc > 1 ? -1 : 0, ms.mc > 1); 8682 hoverAtomIndex = -1; 8683 setFileLoadStatus(FIL.DELETED, null, null, null, null, null); 8684 refreshMeasures(true); 8685 if (bsD0 != null) 8686 bsDeleted.andNot(bsD0); 8687 sm.modifySend(-1, modelIndex, -5, "OK"); 8688 return BSUtil.cardinalityOf(bsDeleted); 8689 } 8690 deleteBonds(BS bsDeleted)8691 public void deleteBonds(BS bsDeleted) { 8692 int modelIndex = ms.bo[bsDeleted.nextSetBit(0)].atom1.mi; 8693 sm.modifySend(-1, modelIndex, 2, "delete bonds " + Escape.eBond(bsDeleted)); 8694 ms.deleteBonds(bsDeleted, false); 8695 sm.modifySend(-1, modelIndex, -2, "OK"); 8696 } 8697 deleteModelAtoms(int modelIndex, int firstAtomIndex, int nAtoms, BS bsModelAtoms)8698 public void deleteModelAtoms(int modelIndex, int firstAtomIndex, int nAtoms, 8699 BS bsModelAtoms) { 8700 // called from ModelCollection.deleteModel 8701 sm.modifySend(-1, modelIndex, 1, 8702 "delete atoms " + Escape.eBS(bsModelAtoms)); 8703 BSUtil.deleteBits(tm.bsFrameOffsets, bsModelAtoms); 8704 getDataManager().deleteModelAtoms(firstAtomIndex, nAtoms, bsModelAtoms); 8705 sm.modifySend(-1, modelIndex, -1, "OK"); 8706 } 8707 getQuaternionFrame()8708 public char getQuaternionFrame() { 8709 return g.quaternionFrame.charAt(g.quaternionFrame.length() == 2 ? 1 : 0); 8710 } 8711 8712 /** 8713 * 8714 * NOTE: This method is called from within a j2sNative block in 8715 * awtjs2d.Platform.java as well as from FileManager.loadImage 8716 * 8717 * @param image 8718 * could be a byte array 8719 * @param nameOrError 8720 * @param echoName 8721 * if this is an echo rather than the background 8722 * @param sco 8723 * delivered in JavaScript from Platform.java 8724 * @return false 8725 */ loadImageData(Object image, String nameOrError, String echoName, Object sco)8726 public boolean loadImageData(Object image, String nameOrError, 8727 String echoName, Object sco) { 8728 ScriptContext sc = (ScriptContext) sco; 8729 if (image == null && nameOrError != null) 8730 scriptEcho(nameOrError); 8731 if (echoName == null) { 8732 setBackgroundImage((image == null ? null : nameOrError), image); 8733 } else if (echoName.startsWith("\1")) { 8734 sm.showImage(echoName, image); 8735 } else if (echoName.startsWith("\0")) { 8736 if (image != null) { 8737 setWindowDimensions(new float[] { apiPlatform.getImageWidth(image), 8738 apiPlatform.getImageHeight(image) }); 8739 } 8740 } else { 8741 shm.loadShape(JC.SHAPE_ECHO); 8742 setShapeProperty(JC.SHAPE_ECHO, "text", nameOrError); 8743 if (image != null) 8744 setShapeProperty(JC.SHAPE_ECHO, "image", image); 8745 } 8746 if (isJS && sc != null) { 8747 sc.mustResumeEval = true; 8748 eval.resumeEval(sc); 8749 } 8750 return false; 8751 } 8752 cd(String dir)8753 public String cd(String dir) { 8754 if (dir == null) { 8755 dir = "."; 8756 } else if (dir.length() == 0) { 8757 setStringProperty("defaultDirectory", ""); 8758 dir = "."; 8759 } 8760 dir = fm.getDefaultDirectory( 8761 dir + (dir.equals("=") ? "" : dir.endsWith("/") ? "X.spt" : "/X.spt")); 8762 if (dir.length() > 0) 8763 setStringProperty("defaultDirectory", dir); 8764 String path = fm.getFilePath(dir + "/", true, false); 8765 if (path.startsWith("file:/")) 8766 FileManager.setLocalPath(this, dir, false); 8767 return dir; 8768 } 8769 8770 // //// Error handling 8771 setErrorMessage(String errMsg, String errMsgUntranslated)8772 public String setErrorMessage(String errMsg, String errMsgUntranslated) { 8773 errorMessageUntranslated = errMsgUntranslated; 8774 if (errMsg != null) 8775 eval.stopScriptThreads(); 8776 return (errorMessage = errMsg); 8777 } 8778 8779 @Override getErrorMessage()8780 public String getErrorMessage() { 8781 return errorMessage; 8782 } 8783 8784 @Override getErrorMessageUn()8785 public String getErrorMessageUn() { 8786 return errorMessageUntranslated == null ? errorMessage 8787 : errorMessageUntranslated; 8788 } 8789 8790 private int currentShapeID = -1; 8791 private String currentShapeState; 8792 setShapeErrorState(int shapeID, String state)8793 public void setShapeErrorState(int shapeID, String state) { 8794 currentShapeID = shapeID; 8795 currentShapeState = state; 8796 } 8797 getShapeErrorState()8798 public String getShapeErrorState() { 8799 if (currentShapeID < 0) 8800 return ""; 8801 shm.releaseShape(currentShapeID); 8802 clearRepaintManager(currentShapeID); 8803 return JC.getShapeClassName(currentShapeID, false) + " " 8804 + currentShapeState; 8805 } 8806 handleError(Error er, boolean doClear)8807 public void handleError(Error er, boolean doClear) { 8808 // almost certainly out of memory; could be missing Jar file 8809 try { 8810 if (doClear) 8811 zapMsg("" + er); // get some breathing room 8812 undoClear(); 8813 if (Logger.getLogLevel() == 0) 8814 Logger.setLogLevel(Logger.LEVEL_INFO); 8815 setCursor(GenericPlatform.CURSOR_DEFAULT); 8816 setBooleanProperty("refreshing", true); 8817 fm.setPathForAllFiles(""); 8818 Logger.error("vwr handling error condition: " + er + " "); 8819 notifyError("Error", "doClear=" + doClear + "; " + er, "" + er); 8820 } catch (Throwable e1) { 8821 try { 8822 Logger.error("Could not notify error " + er + ": due to " + e1); 8823 } catch (Throwable er2) { 8824 // tough luck. 8825 } 8826 } 8827 } 8828 8829 // / User-defined functions 8830 8831 final static Map<String, JmolScriptFunction> staticFunctions = new Hashtable<String, JmolScriptFunction>(); 8832 Map<String, JmolScriptFunction> localFunctions; 8833 getFunctions(boolean isStatic)8834 public Map<String, JmolScriptFunction> getFunctions(boolean isStatic) { 8835 return (isStatic ? staticFunctions : localFunctions); 8836 } 8837 removeFunction(String name)8838 public void removeFunction(String name) { 8839 name = name.toLowerCase(); 8840 JmolScriptFunction function = getFunction(name); 8841 if (function == null) 8842 return; 8843 staticFunctions.remove(name); 8844 localFunctions.remove(name); 8845 } 8846 getFunction(String name)8847 public JmolScriptFunction getFunction(String name) { 8848 if (name == null) 8849 return null; 8850 JmolScriptFunction function = (isStaticFunction(name) ? staticFunctions 8851 : localFunctions).get(name); 8852 return (function == null || function.geTokens() == null ? null : function); 8853 } 8854 isStaticFunction(String name)8855 static boolean isStaticFunction(String name) { 8856 return name.startsWith("static_"); 8857 } 8858 isFunction(String name)8859 public boolean isFunction(String name) { 8860 return (isStaticFunction(name) ? staticFunctions : localFunctions) 8861 .containsKey(name); 8862 } 8863 clearFunctions()8864 public void clearFunctions() { 8865 staticFunctions.clear(); 8866 localFunctions.clear(); 8867 } 8868 addFunction(JmolScriptFunction function)8869 public void addFunction(JmolScriptFunction function) { 8870 String name = function.getName(); 8871 (isStaticFunction(name) ? staticFunctions : localFunctions).put(name, 8872 function); 8873 } 8874 getFunctionCalls(String selectedFunction)8875 public String getFunctionCalls(String selectedFunction) { 8876 return getStateCreator().getFunctionCalls(selectedFunction); 8877 } 8878 8879 /** 8880 * Simple method to ensure that the image creator (which writes files) was in 8881 * fact opened by this vwr and not by some manipulation of the applet. When 8882 * the image creator is used it requires both a vwr object and that vwr's 8883 * private key. But the private key is private, so it is not possible to 8884 * create a useable image creator without working through a vwr's own methods. 8885 * Bob Hanson, 9/20/2009 8886 * 8887 * @param privateKey 8888 * @return true if privateKey matches 8889 * 8890 */ 8891 checkPrivateKey(double privateKey)8892 public boolean checkPrivateKey(double privateKey) { 8893 return privateKey == this.privateKey; 8894 } 8895 bindAction(String desc, String name)8896 public void bindAction(String desc, String name) { 8897 if (haveDisplay) 8898 acm.bind(desc, name); 8899 } 8900 unBindAction(String desc, String name)8901 public void unBindAction(String desc, String name) { 8902 if (haveDisplay) 8903 acm.unbindAction(desc, name); 8904 } 8905 calculateStruts(BS bs1, BS bs2)8906 public int calculateStruts(BS bs1, BS bs2) { 8907 return ms.calculateStruts(bs1 == null ? bsA() : bs1, 8908 bs2 == null ? bsA() : bs2); 8909 } 8910 8911 /** 8912 * This flag if set FALSE: 8913 * 8914 * 1) turns UNDO off for the application 2) turns history off 3) prevents 8915 * saving of inlinedata for later LOAD "" commands 4) turns off the saving of 8916 * changed atom properties 5) does not guarantee accurate state representation 8917 * 6) disallows generation of the state 8918 * 8919 * It is useful in situations such as web sites where memory is an issue and 8920 * there is no need for such. 8921 * 8922 * 8923 * @return TRUE or FALSE 8924 */ getPreserveState()8925 public boolean getPreserveState() { 8926 return (g.preserveState && scm != null); 8927 } 8928 8929 boolean isKiosk; 8930 isKiosk()8931 boolean isKiosk() { 8932 return isKiosk; 8933 } 8934 hasFocus()8935 public boolean hasFocus() { 8936 return (haveDisplay && (isKiosk || apiPlatform.hasFocus(display))); 8937 } 8938 setFocus()8939 public void setFocus() { 8940 if (haveDisplay && !apiPlatform.hasFocus(display)) 8941 apiPlatform.requestFocusInWindow(display); 8942 } 8943 stopMinimization()8944 void stopMinimization() { 8945 if (minimizer != null) { 8946 minimizer.setProperty("stop", null); 8947 } 8948 } 8949 clearMinimization()8950 void clearMinimization() { 8951 if (minimizer != null) 8952 minimizer.setProperty("clear", null); 8953 } 8954 getMinimizationInfo()8955 public String getMinimizationInfo() { 8956 return (minimizer == null ? "" : (String) minimizer.getProperty("log", 0)); 8957 } 8958 checkMinimization()8959 private void checkMinimization() { 8960 refreshMeasures(true); 8961 if (!g.monitorEnergy) 8962 return; 8963 try { 8964 minimize(null, 0, 0, getFrameAtoms(), null, 0, MIN_SILENT); 8965 } catch (Exception e) { 8966 } 8967 echoMessage(getP("_minimizationForceField") + " Energy = " 8968 + getP("_minimizationEnergy")); 8969 } 8970 8971 public static final int MIN_SILENT = 1; 8972 public static final int MIN_HAVE_FIXED = 2; 8973 public static final int MIN_QUICK = 4; 8974 public static final int MIN_ADDH = 8; 8975 public static final int MIN_NO_RANGE = 16; 8976 8977 /** 8978 * 8979 * @param eval 8980 * @param steps 8981 * Integer.MAX_VALUE --> use defaults 8982 * @param crit 8983 * -1 --> use defaults 8984 * @param bsSelected 8985 * @param bsFixed 8986 * @param rangeFixed 8987 * @param flags 8988 * @throws Exception 8989 */ minimize(JmolScriptEvaluator eval, int steps, float crit, BS bsSelected, BS bsFixed, float rangeFixed, int flags)8990 public void minimize(JmolScriptEvaluator eval, int steps, float crit, 8991 BS bsSelected, BS bsFixed, float rangeFixed, int flags) 8992 throws Exception { 8993 8994 boolean isSilent = (flags & MIN_SILENT) == MIN_SILENT; 8995 boolean isQuick = (flags & MIN_QUICK) == MIN_QUICK; 8996 boolean hasRange = (flags & MIN_NO_RANGE) == 0; 8997 boolean addHydrogen = (flags & MIN_ADDH) == MIN_ADDH; 8998 // We only work on atoms that are in frame 8999 9000 String ff = g.forceField; 9001 BS bsInFrame = getFrameAtoms(); 9002 9003 if (bsSelected == null) 9004 bsSelected = getModelUndeletedAtomsBitSet(getVisibleFramesBitSet().nextSetBit(0)); 9005 else if (!isQuick) 9006 bsSelected.and(bsInFrame); 9007 if (isQuick) { 9008 getAuxiliaryInfoForAtoms(bsSelected).put("dimension", "3D"); 9009 bsInFrame = bsSelected; 9010 } 9011 9012 if (rangeFixed <= 0) 9013 rangeFixed = JC.MINIMIZE_FIXED_RANGE; 9014 9015 // we allow for a set of atoms to be fixed, 9016 // but that is only used by default 9017 9018 BS bsMotionFixed = BSUtil 9019 .copy(bsFixed == null ? slm.getMotionFixedAtoms() : bsFixed); 9020 boolean haveFixed = (bsMotionFixed.cardinality() > 0); 9021 if (haveFixed) 9022 bsSelected.andNot(bsMotionFixed); 9023 9024 // We always fix any atoms that 9025 // are in the visible frame set and are within 5 angstroms 9026 // and are not already selected 9027 9028 BS bsNearby = (hasRange ? new BS() 9029 : ms.getAtomsWithinRadius(rangeFixed, bsSelected, true, null)); 9030 bsNearby.andNot(bsSelected); 9031 if (haveFixed) { 9032 bsMotionFixed.and(bsNearby); 9033 } else { 9034 bsMotionFixed = bsNearby; 9035 } 9036 bsMotionFixed.and(bsInFrame); 9037 flags |= ((haveFixed ? MIN_HAVE_FIXED : 0) 9038 | (getBooleanProperty("minimizationSilent") ? MIN_SILENT : 0)); 9039 if (isQuick && getBoolean(T.testflag2)) 9040 return; 9041 if (isQuick) { 9042 { 9043 // carry out a preliminary UFF no-hydrogen calculation 9044 // to clean up benzene rings and amides. 9045 try { 9046 if (!isSilent) 9047 Logger.info("Minimizing " + bsSelected.cardinality() + " atoms"); 9048 getMinimizer(true).minimize(steps, crit, bsSelected, bsMotionFixed, 9049 flags, "UFF"); 9050 } catch (Exception e) { 9051 Logger.error("Minimization error: " + e.toString()); 9052 e.printStackTrace(); 9053 } 9054 9055 } 9056 } 9057 if (addHydrogen) { 9058 BS bsH = addHydrogens(bsSelected, flags); 9059 if (!isQuick) 9060 bsSelected.or(bsH); 9061 } 9062 9063 int n = bsSelected.cardinality(); 9064 if (ff.equals("MMFF") && n > g.minimizationMaxAtoms) { 9065 scriptStatusMsg( 9066 "Too many atoms for minimization (" + n + ">" + g.minimizationMaxAtoms 9067 + "); use 'set minimizationMaxAtoms' to increase this limit", 9068 "minimization: too many atoms"); 9069 return; 9070 } 9071 try { 9072 if (!isSilent) 9073 Logger.info("Minimizing " + bsSelected.cardinality() + " atoms"); 9074 getMinimizer(true).minimize(steps, crit, bsSelected, bsMotionFixed, flags, 9075 (isQuick ? "MMFF" : ff)); 9076 if (isQuick) { 9077 g.forceField = "MMFF"; 9078 setHydrogens(bsSelected); 9079 showString("Minimized by Jmol", false); 9080 } 9081 } catch (JmolAsyncException e) { 9082 if (eval != null) 9083 eval.loadFileResourceAsync(e.getFileName()); 9084 } catch (Exception e) { 9085 Logger.error("Minimization error: " + e.toString()); 9086 e.printStackTrace(); 9087 } 9088 } 9089 setHydrogens(BS bsAtoms)9090 private void setHydrogens(BS bsAtoms) { 9091 int[] nTotal = new int[1]; 9092 P3[][] hatoms = ms.calculateHydrogens(bsAtoms, nTotal, null, 9093 AtomCollection.CALC_H_IGNORE_H | AtomCollection.CALC_H_QUICK); 9094 for (int i = bsAtoms.nextSetBit(0); i >= 0; i = bsAtoms.nextSetBit(i + 1)) { 9095 P3[] pts = hatoms[i]; 9096 if (pts == null || pts.length == 0) 9097 continue; 9098 Atom a = ms.at[i]; 9099 Bond[] b = a.bonds; 9100 for (int j = 0, pt = 0, n = a.getBondCount(); j < n; j++) { 9101 Atom h = b[j].getOtherAtom(a); 9102 if (h.getAtomicAndIsotopeNumber() == 1) { 9103 P3 p = pts[pt++]; 9104 ms.setAtomCoord(h.i, p.x, p.y, p.z); 9105 } 9106 } 9107 } 9108 ms.resetMolecules(); 9109 } 9110 setMotionFixedAtoms(BS bs)9111 public void setMotionFixedAtoms(BS bs) { 9112 slm.setMotionFixedAtoms(bs); 9113 } 9114 getMotionFixedAtoms()9115 public BS getMotionFixedAtoms() { 9116 return slm.getMotionFixedAtoms(); 9117 } 9118 9119 // void rotateArcBall(int x, int y, float factor) { 9120 // tm.rotateArcBall(x, y, factor); 9121 // refresh(REFRESH_SYNC, sm.syncingMouse ? "Mouse: rotateArcBall " + x + " " 9122 // + y + " " + factor : ""); 9123 // } 9124 getAtomicPropertyState(SB commands, byte type, BS bs, String name, float[] data)9125 void getAtomicPropertyState(SB commands, byte type, BS bs, String name, 9126 float[] data) { 9127 getStateCreator().getAtomicPropertyStateBuffer(commands, type, bs, name, 9128 data); 9129 } 9130 getCenterAndPoints(Lst<Object[]> atomSets, boolean addCenter)9131 public P3[][] getCenterAndPoints(Lst<Object[]> atomSets, boolean addCenter) { 9132 return ms.getCenterAndPoints(atomSets, addCenter); 9133 } 9134 writeFileData(String fileName, String type, int modelIndex, Object[] parameters)9135 public String writeFileData(String fileName, String type, int modelIndex, 9136 Object[] parameters) { 9137 return getOutputManager().writeFileData(fileName, type, modelIndex, 9138 parameters); 9139 } 9140 getPdbData(int modelIndex, String type, BS bsAtoms, Object[] parameters, OC oc, boolean getStructure)9141 public String getPdbData(int modelIndex, String type, BS bsAtoms, 9142 Object[] parameters, OC oc, boolean getStructure) { 9143 // plot command 9144 return getPropertyManager().getPdbData(modelIndex, type, 9145 bsAtoms == null ? bsA() : bsAtoms, parameters, oc, getStructure); 9146 } 9147 getGroupsWithin(int nResidues, BS bs)9148 public BS getGroupsWithin(int nResidues, BS bs) { 9149 return ms.getGroupsWithin(nResidues, bs); 9150 } 9151 9152 // parallel processing 9153 9154 public static int nProcessors = 1; 9155 9156 static { 9157 /** 9158 * @j2sIgnore 9159 * 9160 */ 9161 { 9162 nProcessors = Runtime.getRuntime().availableProcessors(); 9163 } 9164 9165 } 9166 9167 public boolean displayLoadErrors = true; 9168 9169 /** 9170 * 9171 * @param shapeID 9172 * @param madOrMad10 9173 * for axes, unitcell, and boundbox 10*mad; otherwise milliangstrom 9174 * diameter 9175 * @param bsSelected 9176 */ setShapeSize(int shapeID, int madOrMad10, BS bsSelected)9177 public void setShapeSize(int shapeID, int madOrMad10, BS bsSelected) { 9178 // might be atoms or bonds 9179 if (bsSelected == null) 9180 bsSelected = bsA(); 9181 shm.setShapeSizeBs(shapeID, madOrMad10, null, bsSelected); 9182 } 9183 setShapeProperty(int shapeID, String propertyName, Object value)9184 public void setShapeProperty(int shapeID, String propertyName, Object value) { 9185 // Eval, BondCollection, StateManager, local 9186 if (shapeID >= 0) 9187 shm.setShapePropertyBs(shapeID, propertyName, value, null); 9188 } 9189 getShapeProperty(int shapeType, String propertyName)9190 public Object getShapeProperty(int shapeType, String propertyName) { 9191 return shm.getShapePropertyIndex(shapeType, propertyName, 9192 Integer.MIN_VALUE); 9193 } 9194 getShapePropertyAsInt(int shapeID, String propertyName)9195 private int getShapePropertyAsInt(int shapeID, String propertyName) { 9196 Object value = getShapeProperty(shapeID, propertyName); 9197 return value == null || !(value instanceof Integer) ? Integer.MIN_VALUE 9198 : ((Integer) value).intValue(); 9199 } 9200 setModelVisibility()9201 public void setModelVisibility() { 9202 if (shm != null) // necessary for file chooser 9203 shm.setModelVisibility(); 9204 } 9205 resetShapes(boolean andCreateNew)9206 public void resetShapes(boolean andCreateNew) { 9207 shm.resetShapes(); 9208 if (andCreateNew) { 9209 shm.loadDefaultShapes(ms); 9210 clearRepaintManager(-1); 9211 } 9212 } 9213 9214 private boolean isParallel; 9215 setParallel(boolean TF)9216 public boolean setParallel(boolean TF) { 9217 return (isParallel = g.multiProcessor && TF); 9218 } 9219 isParallel()9220 public boolean isParallel() { 9221 return g.multiProcessor && isParallel; 9222 } 9223 undoClear()9224 void undoClear() { 9225 actionStates.clear(); 9226 actionStatesRedo.clear(); 9227 } 9228 9229 /** 9230 * 9231 * @param action 9232 * Token.undo or Token.redo 9233 * @param n 9234 * number of steps to go back/forward; 0 for all; -1 for clear; -2 for 9235 * clear BOTH 9236 * 9237 */ undoMoveAction(int action, int n)9238 public void undoMoveAction(int action, int n) { 9239 getStateCreator().undoMoveAction(action, n); 9240 } 9241 undoMoveActionClear(int taintedAtom, int type, boolean clearRedo)9242 public void undoMoveActionClear(int taintedAtom, int type, 9243 boolean clearRedo) { 9244 // called by actionManager 9245 if (g.preserveState) 9246 getStateCreator().undoMoveActionClear(taintedAtom, type, clearRedo); 9247 } 9248 moveAtomWithHydrogens(int atomIndex, int deltaX, int deltaY, int deltaZ, BS bsAtoms)9249 protected void moveAtomWithHydrogens(int atomIndex, int deltaX, int deltaY, 9250 int deltaZ, BS bsAtoms) { 9251 // called by actionManager 9252 stopMinimization(); 9253 if (bsAtoms == null) { 9254 Atom atom = ms.at[atomIndex]; 9255 bsAtoms = BSUtil.newAndSetBit(atomIndex); 9256 Bond[] bonds = atom.bonds; 9257 if (bonds != null) 9258 for (int i = 0; i < bonds.length; i++) { 9259 Atom atom2 = bonds[i].getOtherAtom(atom); 9260 if (atom2.getElementNumber() == 1) 9261 bsAtoms.set(atom2.i); 9262 } 9263 } 9264 moveSelected(deltaX, deltaY, deltaZ, Integer.MIN_VALUE, Integer.MIN_VALUE, 9265 bsAtoms, true, true, 0); 9266 } 9267 isModelPDB(int i)9268 public boolean isModelPDB(int i) { 9269 return ms.am[i].isBioModel; 9270 } 9271 9272 @Override deleteMeasurement(int i)9273 public void deleteMeasurement(int i) { 9274 setShapeProperty(JC.SHAPE_MEASURES, "delete", Integer.valueOf(i)); 9275 } 9276 9277 @Override getSmiles(BS bs)9278 public String getSmiles(BS bs) throws Exception { 9279 return getSmilesOpt(bs, -1, -1, 9280 (bs == null && Logger.debugging ? JC.SMILES_GEN_ATOM_COMMENT : 0) 9281 , 9282 null); 9283 } 9284 9285 @Override getOpenSmiles(BS bs)9286 public String getOpenSmiles(BS bs) throws Exception { 9287 return getSmilesOpt(bs, -1, -1, 9288 JC.SMILES_TYPE_OPENSMILES 9289 | (bs == null && Logger.debugging ? JC.SMILES_GEN_ATOM_COMMENT : 0) 9290 , 9291 "/openstrict///"); 9292 } 9293 getBioSmiles(BS bs)9294 public String getBioSmiles(BS bs) throws Exception { 9295 return getSmilesOpt(bs, -1, -1, 9296 JC.SMILES_GEN_BIO_ALLOW_UNMATCHED_RINGS 9297 | JC.SMILES_GEN_BIO_COV_CROSSLINK | JC.SMILES_GEN_BIO_COMMENT 9298 | (Logger.debugging ? JC.SMILES_GEN_ATOM_COMMENT : 0), 9299 null); 9300 } 9301 9302 /** 9303 * returns the SMILES string for a sequence or atom set does not include 9304 * attached protons on groups 9305 * 9306 * @param bsSelected 9307 * selected atom set or null for current or specified range 9308 * @param index1 9309 * when bsSeleced == null, first atomIndex or -1 for current 9310 * @param index2 9311 * when bsSeleced == null, end atomIndex or -1 for current 9312 * @param flags 9313 * see JC.SMILES_xxxx 9314 * @param options 9315 * e.g. /strict,open/ 9316 * @return SMILES string 9317 * @throws Exception 9318 */ getSmilesOpt(BS bsSelected, int index1, int index2, int flags, String options)9319 public String getSmilesOpt(BS bsSelected, int index1, int index2, int flags, 9320 String options) 9321 throws Exception { 9322 String bioComment = ((flags 9323 & JC.SMILES_GEN_BIO_COMMENT) == JC.SMILES_GEN_BIO_COMMENT 9324 ? getJmolVersion() + " " + getModelName(am.cmi) 9325 : options); 9326 Atom[] atoms = ms.at; 9327 if (bsSelected == null) { 9328 if (index1 < 0 || index2 < 0) { 9329 bsSelected = bsA(); 9330 } else { 9331 if ((flags & JC.SMILES_GEN_BIO) == JC.SMILES_GEN_BIO) { 9332 if (index1 > index2) { 9333 int i = index1; 9334 index1 = index2; 9335 index2 = i; 9336 } 9337 index1 = atoms[index1].group.firstAtomIndex; 9338 index2 = atoms[index2].group.lastAtomIndex; 9339 } 9340 bsSelected = new BS(); 9341 bsSelected.setBits(index1, index2 + 1); 9342 } 9343 } 9344 flags |= (isModel2D(bsSelected) ? JC.SMILES_2D : 0); 9345 SmilesMatcherInterface sm = getSmilesMatcher(); 9346 if (JC.isSmilesCanonical(options)) { 9347 String smiles = sm.getSmiles(atoms, ms.ac, bsSelected, "/noAromatic/", 9348 flags); 9349 return getChemicalInfo(smiles, "smiles", null).trim(); 9350 } 9351 return sm.getSmiles(atoms, ms.ac, bsSelected, bioComment, flags); 9352 } 9353 isModel2D(BS bs)9354 private boolean isModel2D(BS bs) { 9355 Model m = getModelForAtomIndex(bs.nextSetBit(0)); 9356 return (m != null && "2D".equals(m.auxiliaryInfo.get("dimension"))); 9357 } 9358 alert(String msg)9359 public void alert(String msg) { 9360 prompt(msg, null, null, true); 9361 } 9362 prompt(String label, String data, String[] list, boolean asButtons)9363 public String prompt(String label, String data, String[] list, 9364 boolean asButtons) { 9365 return (isKiosk ? "null" 9366 : apiPlatform.prompt(label, data, list, asButtons)); 9367 } 9368 9369 /** 9370 * Ask for new file name when saving or opening a file in Java and saving a file in JavaScript. 9371 * JavaScript use of FileReader goes through loadFileAsync 9372 * 9373 * @param type 9374 * @param fileName 9375 * @param params 9376 * @return new file name 9377 */ dialogAsk(String type, String fileName, Map<String, Object> params)9378 public String dialogAsk(String type, String fileName, 9379 Map<String, Object> params) { 9380 /** 9381 * @j2sNative 9382 * 9383 * return prompt(type, fileName); 9384 * 9385 */ 9386 { 9387 // may have #NOCARTOONS#; and/or "#APPEND#; prepended 9388 return (isKiosk || !haveAccess(ACCESS.ALL) ? null 9389 : sm.dialogAsk(type, fileName, params)); 9390 } 9391 } 9392 9393 public int stateScriptVersionInt = Integer.MAX_VALUE; 9394 9395 private JmolRendererInterface jsExporter3D; 9396 initializeExporter(Map<String, Object> params)9397 public JmolRendererInterface initializeExporter(Map<String, Object> params) { 9398 boolean isJS = params.get("type").equals("JS"); 9399 if (isJS) { 9400 if (jsExporter3D != null) { 9401 jsExporter3D.initializeOutput(this, privateKey, params); 9402 return jsExporter3D; 9403 } 9404 } else { 9405 String fileName = (String) params.get("fileName"); 9406 String[] fullPath = (String[]) params.get("fullPath"); 9407 OC out = getOutputChannel(fileName, fullPath); 9408 if (out == null) 9409 return null; 9410 params.put("outputChannel", out); 9411 } 9412 JmolRendererInterface export3D = (JmolRendererInterface) Interface 9413 .getOption("export.Export3D", this, "export"); 9414 if (export3D == null) 9415 return null; 9416 Object exporter = export3D.initializeExporter(this, privateKey, gdata, 9417 params); 9418 if (isJS && exporter != null) 9419 jsExporter3D = export3D; 9420 return (exporter == null ? null : export3D); 9421 } 9422 getMouseEnabled()9423 public boolean getMouseEnabled() { 9424 return refreshing && !creatingImage; 9425 } 9426 9427 @Override calcAtomsMinMax(BS bs, BoxInfo boxInfo)9428 public void calcAtomsMinMax(BS bs, BoxInfo boxInfo) { 9429 ms.calcAtomsMinMax(bs, boxInfo); 9430 } 9431 9432 /** 9433 * used in autocompletion in console using TAB 9434 * 9435 * @param map 9436 * @param c 9437 */ 9438 @SuppressWarnings("unchecked") getObjectMap(Map<String, ?> map, char c)9439 public void getObjectMap(Map<String, ?> map, char c) { 9440 switch (c) { 9441 case '{': 9442 if (getScriptManager() != null) { 9443 Map<String, Object> m = (Map<String, Object>) map; 9444 if (definedAtomSets != null) 9445 m.putAll(definedAtomSets); 9446 T.getTokensType(m, T.predefinedset); 9447 } 9448 return; 9449 case '$': 9450 case '0': 9451 shm.getObjectMap(map, c == '$'); 9452 return; 9453 } 9454 } 9455 setPicked(int atomIndex, boolean andReset)9456 public void setPicked(int atomIndex, boolean andReset) { 9457 SV pickedSet = null; 9458 SV pickedList = null; 9459 if (atomIndex >= 0) { 9460 if (andReset) 9461 setPicked(-1, false); 9462 g.setI("_atompicked", atomIndex); 9463 pickedSet = (SV) g.getParam("picked", true); 9464 pickedList = (SV) g.getParam("pickedList", true); 9465 } 9466 if (pickedSet == null || pickedSet.tok != T.bitset) { 9467 pickedSet = SV.newV(T.bitset, new BS()); 9468 pickedList = SV.getVariableList(new Lst<Object>()); 9469 g.setUserVariable("picked", pickedSet); 9470 g.setUserVariable("pickedList", pickedList); 9471 } 9472 if (atomIndex < 0) 9473 return; 9474 SV.getBitSet(pickedSet, false).set(atomIndex); 9475 SV p = pickedList.pushPop(null, null); 9476 // don't allow double click 9477 if (p.tok == T.bitset) 9478 pickedList.pushPop(null, p); 9479 if (p.tok != T.bitset || !((BS) p.value).get(atomIndex)) 9480 pickedList.pushPop(null, 9481 SV.newV(T.bitset, BSUtil.newAndSetBit(atomIndex))); 9482 } 9483 9484 /** 9485 * Run a script using the script function script("xxxxxx") using direct script 9486 * tokens for script ( "xxxxxxx" ) 9487 * 9488 */ 9489 @Override runScript(String script)9490 public String runScript(String script) { 9491 return "" + evaluateExpression(new T[][] { new T[] { T.tokenScript, 9492 T.tokenLeftParen, SV.newS(script), T.tokenRightParen } }); 9493 } 9494 9495 /** 9496 * formerly runScript(), this method really can ONLY be called by the viewer 9497 * being run from an already-running script. If it is invoked by a separate 9498 * thread, it can wreak havoc on any queued thread, since they are not thread 9499 * safe. 9500 * 9501 * @param script 9502 * @return output of the script. 9503 */ 9504 @Override runScriptCautiously(String script)9505 public String runScriptCautiously(String script) { 9506 // from isosurface reading JVXL file with slab 9507 SB outputBuffer = new SB(); 9508 try { 9509 if (getScriptManager() == null) 9510 return null; 9511 eval.runScriptBuffer(script, outputBuffer, false); 9512 } catch (Exception e) { 9513 return eval.getErrorMessage(); 9514 } 9515 return outputBuffer.toString(); 9516 } 9517 setFrameDelayMs(long millis)9518 public void setFrameDelayMs(long millis) { 9519 ms.setFrameDelayMs(millis, getVisibleFramesBitSet()); 9520 } 9521 getBaseModelBitSet()9522 public BS getBaseModelBitSet() { 9523 return ms.getModelAtomBitSetIncludingDeleted(getJDXBaseModelIndex(am.cmi), 9524 true); 9525 } 9526 9527 public Map<String, Object> timeouts; 9528 clearTimeouts()9529 public void clearTimeouts() { 9530 if (timeouts != null) 9531 TimeoutThread.clear(timeouts); 9532 } 9533 setTimeout(String name, int mSec, String script)9534 public void setTimeout(String name, int mSec, String script) { 9535 if (!haveDisplay || headless || autoExit) 9536 return; 9537 if (name == null) { 9538 clearTimeouts(); 9539 return; 9540 } 9541 if (timeouts == null) { 9542 timeouts = new Hashtable<String, Object>(); 9543 } 9544 TimeoutThread.setTimeout(this, timeouts, name, mSec, script); 9545 } 9546 triggerTimeout(String name)9547 public void triggerTimeout(String name) { 9548 if (!haveDisplay || timeouts == null) 9549 return; 9550 TimeoutThread.trigger(timeouts, name); 9551 } 9552 clearTimeout(String name)9553 public void clearTimeout(String name) { 9554 setTimeout(name, 0, null); 9555 } 9556 showTimeout(String name)9557 public String showTimeout(String name) { 9558 return (haveDisplay ? TimeoutThread.showTimeout(timeouts, name) : ""); 9559 } 9560 getOrCalcPartialCharges(BS bsSelected, BS bsIgnore)9561 public float[] getOrCalcPartialCharges(BS bsSelected, BS bsIgnore) 9562 throws JmolAsyncException { 9563 if (bsSelected == null) 9564 bsSelected = bsA(); 9565 bsSelected = BSUtil.copy(bsSelected); 9566 BSUtil.andNot(bsSelected, bsIgnore); 9567 BSUtil.andNot(bsSelected, ms.bsPartialCharges); 9568 if (!bsSelected.isEmpty()) 9569 calculatePartialCharges(bsSelected); 9570 return ms.getPartialCharges(); 9571 } 9572 calculatePartialCharges(BS bsSelected)9573 public void calculatePartialCharges(BS bsSelected) throws JmolAsyncException { 9574 if (bsSelected == null || bsSelected.isEmpty()) 9575 bsSelected = getFrameAtoms(); 9576 if (bsSelected.isEmpty()) 9577 return; 9578 // // this forces an array if it does not exist 9579 // setAtomProperty(BSUtil.newAndSetBit(pt), T.partialcharge, 0, 1f, null, 9580 // null, null); 9581 Logger.info("Calculating MMFF94 partial charges for " 9582 + bsSelected.cardinality() + " atoms"); 9583 getMinimizer(true).calculatePartialCharges(ms, bsSelected, null); 9584 } 9585 setCurrentModelID(String id)9586 public void setCurrentModelID(String id) { 9587 int modelIndex = am.cmi; 9588 if (modelIndex >= 0) 9589 ms.setInfo(modelIndex, "modelID", id); 9590 } 9591 cacheClear()9592 public void cacheClear() { 9593 // script: reset cache 9594 fm.cacheClear(); 9595 ligandModelSet = null; 9596 ligandModels = null; 9597 ms.clearCache(); 9598 } 9599 9600 /** 9601 * JSInterface -- allows saving files in memory for later retrieval 9602 * 9603 * @param key 9604 * @param data 9605 * 9606 */ 9607 cachePut(String key, Object data)9608 public void cachePut(String key, Object data) { 9609 // PyMOL reader and isosurface 9610 // HTML5/JavaScript load ? and script ? 9611 Logger.info("Viewer cachePut " + key); 9612 fm.cachePut(key, data); 9613 } 9614 cacheFileByName(String fileName, boolean isAdd)9615 public int cacheFileByName(String fileName, boolean isAdd) { 9616 // cache command in script 9617 if (fileName == null) { 9618 cacheClear(); 9619 return -1; 9620 } 9621 return fm.cacheFileByNameAdd(fileName, isAdd); 9622 } 9623 clearThreads()9624 public void clearThreads() { 9625 if (eval != null) 9626 eval.stopScriptThreads(); 9627 stopMinimization(); 9628 tm.clearThreads(); 9629 setAnimationOn(false); 9630 } 9631 getEvalContextAndHoldQueue(JmolScriptEvaluator eval)9632 public ScriptContext getEvalContextAndHoldQueue(JmolScriptEvaluator eval) { 9633 if (eval == null || !(isJS || testAsync)) 9634 return null; 9635 eval.pushContextDown(ScriptEval.CONTEXT_HOLD_QUEUE); 9636 ScriptContext sc = eval.getThisContext(); 9637 sc.setMustResume(); 9638 sc.isJSThread = true; 9639 queueOnHold = true; 9640 return sc; 9641 } 9642 getDefaultPropertyParam(int propertyID)9643 public String getDefaultPropertyParam(int propertyID) { 9644 return getPropertyManager().getDefaultPropertyParam(propertyID); 9645 } 9646 getPropertyNumber(String name)9647 public int getPropertyNumber(String name) { 9648 return getPropertyManager().getPropertyNumber(name); 9649 } 9650 checkPropertyParameter(String name)9651 public boolean checkPropertyParameter(String name) { 9652 return getPropertyManager().checkPropertyParameter(name); 9653 } 9654 extractProperty(Object property, Object args, int pt)9655 public Object extractProperty(Object property, Object args, int pt) { 9656 return getPropertyManager().extractProperty(property, args, pt, null, 9657 false); 9658 } 9659 9660 //// requiring ScriptEvaluator: 9661 addHydrogens(BS bsAtoms, int flags)9662 public BS addHydrogens(BS bsAtoms, int flags) { 9663 boolean isSilent = ((flags & MIN_SILENT) == MIN_SILENT); 9664 boolean isQuick = ((flags & MIN_QUICK) == MIN_QUICK); 9665 boolean doAll = (bsAtoms == null); 9666 if (bsAtoms == null) 9667 bsAtoms = getModelUndeletedAtomsBitSet( 9668 getVisibleFramesBitSet().length() - 1); 9669 BS bsB = new BS(); 9670 if (bsAtoms.isEmpty()) 9671 return bsB; 9672 // if (!ms.isAtomInLastModel(bsAtoms.nextSetBit(0))) 9673 // return bsB; 9674 Lst<Atom> vConnections = new Lst<Atom>(); 9675 P3[] pts = getAdditionalHydrogens(bsAtoms, vConnections, 9676 flags | (doAll ? AtomCollection.CALC_H_DOALL : 0)); 9677 boolean wasAppendNew = false; 9678 wasAppendNew = g.appendNew; 9679 if (pts.length > 0) { 9680 clearModelDependentObjects(); 9681 try { 9682 bsB = (isQuick ? ms.addHydrogens(vConnections, pts) 9683 : addHydrogensInline(bsAtoms, vConnections, pts)); 9684 } catch (Exception e) { 9685 System.out.println(e.toString()); 9686 // ignore 9687 } 9688 if (wasAppendNew) 9689 g.appendNew = true; 9690 } 9691 if (!isSilent) 9692 scriptStatus(GT.i(GT.$("{0} hydrogens added"), pts.length)); 9693 return bsB; 9694 } 9695 addHydrogensInline(BS bsAtoms, Lst<Atom> vConnections, P3[] pts)9696 public BS addHydrogensInline(BS bsAtoms, Lst<Atom> vConnections, P3[] pts) 9697 throws Exception { 9698 if (getScriptManager() == null) 9699 return null; 9700 return scm.addHydrogensInline(bsAtoms, vConnections, pts); 9701 } 9702 9703 @Override evalFunctionFloat(Object func, Object params, float[] values)9704 public float evalFunctionFloat(Object func, Object params, float[] values) { 9705 return (getScriptManager() == null ? 0 9706 : eval.evalFunctionFloat(func, params, values)); 9707 } 9708 evalParallel(ScriptContext context, ShapeManager shapeManager)9709 public boolean evalParallel(ScriptContext context, 9710 ShapeManager shapeManager) { 9711 displayLoadErrors = false; 9712 boolean isOK = getScriptManager() != null && eval.evalParallel(context, 9713 (shapeManager == null ? this.shm : shapeManager)); 9714 displayLoadErrors = true; 9715 return isOK; 9716 } 9717 9718 /** 9719 * synchronized here trapped the eventQueue; see also 9720 * evaluateExpressionAsVariable 9721 * 9722 */ 9723 @Override evaluateExpression(Object stringOrTokens)9724 public Object evaluateExpression(Object stringOrTokens) { 9725 return (getScriptManager() == null ? null 9726 : eval.evaluateExpression(stringOrTokens, false, false)); 9727 } 9728 9729 @Override evaluateExpressionAsVariable(Object stringOrTokens)9730 public SV evaluateExpressionAsVariable(Object stringOrTokens) { 9731 return (getScriptManager() == null ? null 9732 : (SV) eval.evaluateExpression(stringOrTokens, true, false)); 9733 } 9734 getAtomBitSet(Object atomExpression)9735 public BS getAtomBitSet(Object atomExpression) { 9736 // SMARTS searching 9737 // getLigandInfo 9738 // used in interaction with JSpecView 9739 // used for set picking SELECT 9740 9741 if (atomExpression instanceof BS) 9742 return slm.excludeAtoms((BS) atomExpression, false); 9743 getScriptManager(); 9744 return getAtomBitSetEval(eval, atomExpression); 9745 } 9746 getScriptContext(String why)9747 public ScriptContext getScriptContext(String why) { 9748 return (getScriptManager() == null ? null : eval.getScriptContext(why)); 9749 } 9750 getAtomDefs(Map<String, Object> names)9751 public String getAtomDefs(Map<String, Object> names) { 9752 Lst<String> keys = new Lst<String>(); 9753 for (Map.Entry<String, ?> e : names.entrySet()) 9754 if (e.getValue() instanceof BS) 9755 keys.addLast("{" + e.getKey() + "} <" 9756 + ((BS) e.getValue()).cardinality() + " atoms>\n"); 9757 int n = keys.size(); 9758 String[] k = new String[n]; 9759 keys.toArray(k); 9760 Arrays.sort(k); 9761 SB sb = new SB(); 9762 for (int i = 0; i < n; i++) 9763 sb.append(k[i]); 9764 return sb.append("\n").toString(); 9765 } 9766 setCGO(Lst<Object> info)9767 public void setCGO(Lst<Object> info) { 9768 shm.loadShape(JC.SHAPE_CGO); 9769 shm.setShapePropertyBs(JC.SHAPE_CGO, "setCGO", info, null); 9770 } 9771 setModelSet(ModelSet modelSet)9772 public void setModelSet(ModelSet modelSet) { 9773 this.ms = mm.modelSet = modelSet; 9774 } 9775 setObjectProp(String id, int tokCommand)9776 public String setObjectProp(String id, int tokCommand) { 9777 // for PyMOL session scene setting 9778 getScriptManager(); 9779 if (id == null) 9780 id = "*"; 9781 return (eval == null ? null : eval.setObjectPropSafe(id, tokCommand)); 9782 } 9783 setDihedrals(float[] dihedralList, BS[] bsBranches, float rate)9784 public void setDihedrals(float[] dihedralList, BS[] bsBranches, float rate) { 9785 if (bsBranches == null) 9786 bsBranches = ms.getBsBranches(dihedralList); 9787 ms.setDihedrals(dihedralList, bsBranches, rate); 9788 } 9789 9790 private boolean chainCaseSpecified; 9791 9792 /** 9793 * Create a unique integer for any chain string. Note that if there are any 9794 * chains that are more than a single character, chainCaseSensitive is 9795 * automatically set TRUE 9796 * 9797 * 9798 * @param id 9799 * < 256 is just the character of a single-character upper-case chain 9800 * id, upper or lower case query; 9801 * 9802 * >= 256 < 300 is lower case found in structure 9803 * 9804 * @param isAssign 9805 * from a file reader, not a select query 9806 * 9807 * @return i 9808 */ getChainID(String id, boolean isAssign)9809 public int getChainID(String id, boolean isAssign) { 9810 // if select :a and there IS chain "a" in a structure, 9811 // then we return that id, and all is good. Chain selectivity 9812 // is inforced, and we will find it. 9813 Integer iboxed = (Integer) chainMap.get(id); 9814 if (iboxed != null) 9815 return iboxed.intValue(); 9816 int i = id.charAt(0); 9817 if (id.length() > 1) { 9818 i = 300 + chainList.size(); 9819 } else if ((isAssign || chainCaseSpecified) && 97 <= i && i <= 122) { // lower case 9820 i += 159; // starts at 256 9821 } 9822 if (i >= 256) { 9823 iboxed = (Integer) chainMap.get(id); 9824 if (iboxed != null) 9825 return iboxed.intValue(); 9826 //this will force chainCaseSensitive when it is necessary 9827 chainCaseSpecified |= isAssign; 9828 chainList.addLast(id); 9829 } 9830 // if select :a and there is NO chain "a" in the structure, 9831 // there still might be an "A" and we cannot check for 9832 // chain case sensitivity yet, as we are parsing the script, 9833 // not processing it. So we just store this one as 97-122. 9834 9835 iboxed = Integer.valueOf(i); 9836 chainMap.put(iboxed, id); 9837 chainMap.put(id, iboxed); 9838 return i; 9839 } 9840 getChainIDStr(int id)9841 public String getChainIDStr(int id) { 9842 return (String) chainMap.get(Integer.valueOf(id)); 9843 } 9844 getScriptQueueInfo()9845 public Boolean getScriptQueueInfo() { 9846 return (scm != null && scm.isQueueProcessing() ? Boolean.TRUE 9847 : Boolean.FALSE); 9848 } 9849 9850 JmolNMRInterface nmrCalculation; 9851 getNMRCalculation()9852 public JmolNMRInterface getNMRCalculation() { 9853 return (nmrCalculation == null 9854 ? (nmrCalculation = (JmolNMRInterface) Interface 9855 .getOption("quantum.NMRCalculation", this, "script")) 9856 .setViewer(this) 9857 : nmrCalculation); 9858 } 9859 getDistanceUnits(String s)9860 public String getDistanceUnits(String s) { 9861 if (s == null) 9862 s = getDefaultMeasurementLabel(2); 9863 int pt = s.indexOf("//"); 9864 return (pt < 0 ? g.measureDistanceUnits : s.substring(pt + 2)); 9865 } 9866 calculateFormalCharges(BS bs)9867 public int calculateFormalCharges(BS bs) { 9868 return ms.fixFormalCharges(bs == null ? bsA() : bs); 9869 } 9870 setModulation(BS bs, boolean isOn, P3 t1, boolean isQ)9871 public void setModulation(BS bs, boolean isOn, P3 t1, boolean isQ) { 9872 if (isQ) 9873 g.setO("_modt", Escape.eP(t1)); 9874 ms.setModulation(bs == null ? getAllAtoms() : bs, isOn, t1, isQ); 9875 refreshMeasures(true); 9876 } 9877 checkInMotion(int state)9878 public void checkInMotion(int state) { 9879 switch (state) { 9880 case 0: // off 9881 setTimeout("_SET_IN_MOTION_", 0, null); 9882 break; 9883 case 1: // start 1-second timer (by default) 9884 if (!inMotion) 9885 setTimeout("_SET_IN_MOTION_", g.hoverDelayMs * 2, "!setInMotion"); 9886 break; 9887 case 2: // trigger, from a timeout thread 9888 setInMotion(true); 9889 refresh(REFRESH_SYNC_MASK, "timeoutThread set in motion"); 9890 break; 9891 } 9892 } 9893 9894 /** 9895 * check motion for rendering during mouse movement, spin, vibration, and 9896 * animation 9897 * 9898 * @param tok 9899 * @return TRUE if allowed 9900 */ checkMotionRendering(int tok)9901 public boolean checkMotionRendering(int tok) { 9902 if (!getInMotion(true) && !tm.spinOn && !tm.vibrationOn && !am.animationOn) 9903 return true; 9904 if (g.wireframeRotation) 9905 return false; 9906 int n = 0; 9907 switch (tok) { 9908 case T.bonds: 9909 case T.atoms: 9910 n = 2; 9911 break; 9912 case T.ellipsoid: 9913 n = 3; 9914 break; 9915 case T.geosurface: 9916 n = 4; 9917 break; 9918 case T.cartoon: 9919 n = 5; 9920 break; 9921 case T.mesh: 9922 n = 6; 9923 break; 9924 case T.translucent: 9925 n = 7; 9926 break; 9927 case T.antialiasdisplay: 9928 n = 8; 9929 break; 9930 } 9931 return g.platformSpeed >= n; 9932 } 9933 9934 // /////////////////////////////////////////////////////////////// 9935 // delegated to JmolFileAdapter 9936 // /////////////////////////////////////////////////////////////// 9937 openExportChannel(double privateKey, String fileName, boolean asWriter)9938 public OC openExportChannel(double privateKey, String fileName, 9939 boolean asWriter) 9940 throws IOException { 9941 return getOutputManager().openOutputChannel(privateKey, fileName, asWriter, 9942 false); 9943 } 9944 9945 /*default*/String logFileName; 9946 9947 @Override log(String data)9948 public void log(String data) { 9949 if (data != null) 9950 getOutputManager().logToFile(data); 9951 } 9952 getLogFileName()9953 public String getLogFileName() { 9954 return (logFileName == null ? "" : logFileName); 9955 } 9956 getCommands(Map<String, BS> htDefine, Map<String, BS> htMore, String select)9957 public String getCommands(Map<String, BS> htDefine, Map<String, BS> htMore, 9958 String select) { 9959 return getStateCreator().getCommands(htDefine, htMore, select); 9960 } 9961 allowCapture()9962 public boolean allowCapture() { 9963 return !isApplet || isSignedApplet; 9964 } 9965 compileExpr(String expr)9966 public T[] compileExpr(String expr) { 9967 Object o = (getScriptManager() == null ? null 9968 : eval.evaluateExpression(expr, false, true)); 9969 return (o instanceof T[] ? (T[]) o : new T[] { T.o(T.string, expr) }); 9970 } 9971 checkSelect(Map<String, SV> h, T[] value)9972 public boolean checkSelect(Map<String, SV> h, T[] value) { 9973 return getScriptManager() != null && eval.checkSelect(h, value); 9974 } 9975 getAnnotationInfo(SV d, String match, int type)9976 public String getAnnotationInfo(SV d, String match, int type) { 9977 return getAnnotationParser(type == T.dssr).getAnnotationInfo(this, d, match, 9978 type, am.cmi); 9979 } 9980 getAtomValidation(String type, Atom atom)9981 public Lst<Float> getAtomValidation(String type, Atom atom) { 9982 return getAnnotationParser(false).getAtomValidation(this, type, atom); 9983 } 9984 dragMinimizeAtom(final int iAtom)9985 void dragMinimizeAtom(final int iAtom) { 9986 stopMinimization(); 9987 BS bs = (getMotionFixedAtoms().isEmpty() 9988 ? ms.getAtoms((ms.isAtomPDB(iAtom) ? T.group : T.molecule), 9989 BSUtil.newAndSetBit(iAtom)) 9990 : BSUtil.setAll(ms.ac)); 9991 try { 9992 minimize(null, Integer.MAX_VALUE, 0, bs, null, 0, 0); 9993 } catch (Exception e) { 9994 if (!async) 9995 return; 9996 final Viewer me = this; 9997 @SuppressWarnings("unused") 9998 Runnable r = new Runnable() { 9999 @Override 10000 public void run() { 10001 me.dragMinimizeAtom(iAtom); 10002 } 10003 }; 10004 /** 10005 * @j2sNative 10006 * 10007 * setTimeout(function(){r.run()}, 100); 10008 * 10009 */ 10010 { 10011 } 10012 } 10013 } 10014 10015 BioResolver jbr; 10016 getJBR()10017 public BioResolver getJBR() { 10018 return (jbr == null 10019 ? jbr = ((BioResolver) Interface 10020 .getInterface("org.jmol.modelsetbio.BioResolver", this, "file")) 10021 .setViewer(this) 10022 : jbr); 10023 } 10024 checkMenuUpdate()10025 public void checkMenuUpdate() { 10026 if (jmolpopup != null) 10027 jmolpopup.jpiUpdateComputedMenus(); 10028 } 10029 10030 private JmolChimeMessenger jcm; 10031 getChimeMessenger()10032 public JmolChimeMessenger getChimeMessenger() { 10033 return (jcm == null 10034 ? jcm = ((JmolChimeMessenger) Interface 10035 .getInterface("org.jmol.viewer.ChimeMessenger", this, "script")) 10036 .set(this) 10037 : jcm); 10038 } 10039 getAuxiliaryInfoForAtoms(Object atomExpression)10040 public Map<String, Object> getAuxiliaryInfoForAtoms(Object atomExpression) { 10041 return ms 10042 .getAuxiliaryInfo(ms.getModelBS(getAtomBitSet(atomExpression), false)); 10043 } 10044 10045 private JSJSONParser jsonParser; 10046 getJSJSONParser()10047 private JSJSONParser getJSJSONParser() { 10048 return (jsonParser == null 10049 ? jsonParser = (JSJSONParser) Interface 10050 .getInterface("javajs.util.JSJSONParser", this, "script") 10051 : jsonParser); 10052 } 10053 parseJSON(String str)10054 public Object parseJSON(String str) { 10055 return (str == null ? null 10056 : (str = str.trim()).startsWith("{") ? parseJSONMap(str) 10057 : parseJSONArray(str)); 10058 } 10059 parseJSONMap(String jsonMap)10060 public Map<String, Object> parseJSONMap(String jsonMap) { 10061 return getJSJSONParser().parseMap(jsonMap, true); 10062 } 10063 10064 @SuppressWarnings("unchecked") parseJSONArray(String jsonArray)10065 public Lst<Object> parseJSONArray(String jsonArray) { 10066 return (Lst<Object>) getJSJSONParser().parse(jsonArray, true); 10067 } 10068 10069 /** 10070 * Retrieve a Symmetry object, possibly re-using an old one. 10071 * 10072 * @return org.jmol.symmetry.Symmetry object 10073 */ getSymTemp()10074 public SymmetryInterface getSymTemp() { 10075 return Interface.getSymmetry(this, "ms"); 10076 } 10077 setWindowDimensions(float[] dims)10078 public void setWindowDimensions(float[] dims) { 10079 resizeInnerPanel((int) dims[0], (int) dims[1]); 10080 } 10081 10082 private Triangulator triangulator; 10083 getTriangulator()10084 public Triangulator getTriangulator() { 10085 return (triangulator == null 10086 ? (triangulator = (Triangulator) Interface.getUtil("Triangulator", this, 10087 "script")) 10088 : triangulator); 10089 } 10090 getCurrentModelAuxInfo()10091 public Map<String, Object> getCurrentModelAuxInfo() { 10092 return (am.cmi >= 0 ? ms.getModelAuxiliaryInfo(am.cmi) : null); 10093 } 10094 startNBO(String options)10095 public void startNBO(String options) { 10096 Map<String, Object> htParams = new Hashtable<String, Object>(); 10097 htParams.put("service", "nbo"); 10098 htParams.put("action", "showPanel"); 10099 htParams.put("options", options); 10100 sm.processService(htParams); 10101 } 10102 10103 /** 10104 * startup -U nbo option 10105 * 10106 * @param plugin 10107 */ startPlugin(String plugin)10108 public void startPlugin(String plugin) { 10109 10110 // for now, just NBO; need a way to bootstrap this 10111 10112 if ("nbo".equalsIgnoreCase(plugin)) 10113 startNBO("all"); 10114 } 10115 10116 private NBOParser nboParser; 10117 connectNBO(String type)10118 public void connectNBO(String type) { 10119 if (am.cmi < 0) 10120 return; 10121 getNBOParser().connectNBO(am.cmi, type); 10122 } 10123 getNBOParser()10124 private NBOParser getNBOParser() { 10125 return (nboParser == null ? nboParser = ((NBOParser) Interface.getInterface( 10126 "org.jmol.adapter.readers.quantum.NBOParser", this, "script")).set(this) 10127 : nboParser); 10128 } 10129 getNBOAtomLabel(Atom atom)10130 public String getNBOAtomLabel(Atom atom) { 10131 return getNBOParser().getNBOAtomLabel(atom); 10132 } 10133 calculateChirality(BS bsAtoms)10134 public String calculateChirality(BS bsAtoms) { 10135 if (bsAtoms == null) 10136 bsAtoms = bsA(); 10137 return ms.calculateChiralityForAtoms(bsAtoms, true); 10138 } 10139 getSubstructureSetArray(String pattern, BS bsSelected, int flags)10140 public BS[] getSubstructureSetArray(String pattern, BS bsSelected, int flags) 10141 throws Exception { 10142 return getSmilesMatcher().getSubstructureSetArray(pattern, ms.at, ms.ac, 10143 bsSelected, null, flags); 10144 } 10145 getSubstructureSetArrayForNodes(String pattern, Node[] nodes, int flags)10146 public BS[] getSubstructureSetArrayForNodes(String pattern, Node[] nodes, 10147 int flags) 10148 throws Exception { 10149 return getSmilesMatcher().getSubstructureSetArray(pattern, nodes, 10150 nodes.length, null, null, flags); 10151 } 10152 getSmilesAtoms(String smiles)10153 public Node[] getSmilesAtoms(String smiles) throws Exception { 10154 return getSmilesMatcher().getAtoms(smiles); 10155 } 10156 calculateChiralityForSmiles(String smiles)10157 public String[] calculateChiralityForSmiles(String smiles) { 10158 try { 10159 return Interface.getSymmetry(this, "ms") 10160 .calculateCIPChiralityForSmiles(this, smiles); 10161 } catch (Exception e) { 10162 return null; 10163 } 10164 } 10165 getPdbID()10166 public String getPdbID() { 10167 return (ms.getInfo(am.cmi, "isPDB") == Boolean.TRUE 10168 ? (String) ms.getInfo(am.cmi, "pdbID") 10169 : null); 10170 } 10171 10172 /** 10173 * get a value from the current model's Model.auxiliaryInfo 10174 * 10175 * @param key 10176 * @return value, or null if there is no SINGLE current model 10177 */ getModelInfo(String key)10178 public Object getModelInfo(String key) { 10179 return ms.getInfo(am.cmi, key); 10180 } 10181 notifyScriptEditor(int msWalltime, Object[] data)10182 public void notifyScriptEditor(int msWalltime, Object[] data) { 10183 if (scriptEditor != null) { 10184 scriptEditor.notify(msWalltime, data); 10185 } 10186 } 10187 sendConsoleMessage(String msg)10188 public void sendConsoleMessage(String msg) { 10189 if (appConsole != null) 10190 appConsole.sendConsoleMessage(msg); 10191 } 10192 10193 /** 10194 * 10195 * @param nameOrData 10196 * could be name or [name,value] 10197 * @return value 10198 */ getModelkitProperty(Object nameOrData)10199 public Object getModelkitProperty(Object nameOrData) { 10200 return (modelkit == null ? null : modelkit.getProperty(nameOrData)); 10201 } 10202 setModelkitProperty(String key, Object value)10203 public Object setModelkitProperty(String key, Object value) { 10204 return (modelkit == null ? null : modelkit.setProperty(key, value)); 10205 } 10206 10207 /** 10208 * A general method for retrieving symmetry information with full capability 10209 * of the symop() scripting function. 10210 * 10211 * @param iatom 10212 * atom index specifying the model set and used for pt1 if that is null 10213 * and also for matching element type. 10214 * @param xyz 10215 * the desired Jones-Faithful representation of the symmetry operation 10216 * or null 10217 * @param iOp 10218 * the desired symmetry operation [1-n] or 0 10219 * @param translation [i j k] translational addition to symop 10220 * @param pt1 10221 * the starting point, or null if to use iatom or otherwise unnecessary 10222 * @param pt2 10223 * the target point, if this is a point-to-point determination, or the 10224 * offset if not and options is nonzero 10225 * @param type 10226 * a token type such as T.list or T.array 10227 * @param desc 10228 * if type == T.nada (0), a name evaluating to a type, or one of the 10229 * special names: "info", "description", "matrix", "axispoint", or 10230 * "time" (as in time-reversal); otherwise, if type == T.draw, the root 10231 * id given to a returned DRAW command set 10232 * @param scaleFactor 10233 * if nonzero and type == T.draw, a scaling factor to be applied to the 10234 * rotational vector 10235 * @param nth 10236 * in the case of a point-to-point determination, the nth matching 10237 * operator, or 0 for "all" 10238 * @param options 10239 * if nonzero, a option, currently just T.offset, indicating that pt1 10240 * is an {i j k} offset from cell 555 10241 * @return string, Object[], or Lst<Object[]> 10242 */ getSymmetryInfo(int iatom, String xyz, int iOp, P3 translation, P3 pt1, P3 pt2, int type, String desc, float scaleFactor, int nth, int options)10243 public Object getSymmetryInfo(int iatom, String xyz, int iOp, P3 translation, P3 pt1, 10244 P3 pt2, int type, String desc, 10245 float scaleFactor, int nth, int options) { 10246 try { 10247 return getSymTemp().getSymmetryInfoAtom(ms, iatom, xyz, iOp, translation, pt1, 10248 pt2, desc, type, scaleFactor, nth, options); 10249 } catch (Exception e) { 10250 System.out.println("Exception in Viewer.getSymmetryInfo: " + e); 10251 if (!isJS) 10252 e.printStackTrace(); 10253 return null; 10254 } 10255 } 10256 10257 /** 10258 * 10259 * @param i 10260 * Integer.MIN_VALUE initializes the bond index 10261 */ setModelKitRotateBondIndex(int i)10262 public void setModelKitRotateBondIndex(int i) { 10263 if (modelkit != null) { 10264 modelkit.setProperty("rotateBondIndex", Integer.valueOf(i)); 10265 } 10266 } 10267 10268 private Map<String, Object> macros; 10269 10270 /** 10271 * retrieve macros.json from the directory 10272 * 10273 * @param key 10274 * @return the macro path 10275 */ 10276 @SuppressWarnings("unchecked") getMacro(String key)10277 public String getMacro(String key) { 10278 if (macros == null || macros.isEmpty()) { 10279 try { 10280 String s = getAsciiFileOrNull(g.macroDirectory + "/macros.json"); 10281 macros = (Map<String, Object>) parseJSON(s); 10282 } catch (Exception e) { 10283 macros = new Hashtable<String, Object>(); 10284 } 10285 // { 10286 // aflow:{path:"https://chemapps.stolaf.edu/jmol/macros/AFLOW.spt", title:"AFLOW macros"}, 10287 // bz:{path:"https://chemapps.stolaf.edu/jmol/macros/bz.spt", title: "Brillouin Zone/Wigner-Seitz macros"}, 10288 // topology:{path:"https://chemapps.stolaf.edu/jmol/macros/topology.spt", title: "Topology CIF macros"}, 10289 // topond:{path:"https://chemapps.stolaf.edu/jmol/macros/topond.spt", title: "CRYSTAL/TOPOND macros"}, 10290 // crystal:{path:"https://chemapps.stolaf.edu/jmol/macros/crystal.spt", title: "CRYSTAL macros"} 10291 // }; 10292 } 10293 if (key == null) { 10294 SB s = new SB(); 10295 for (String k : macros.keySet()) { 10296 Object a = macros.get(k); 10297 s.append(k).append("\t").appendO(a).append("\n"); 10298 } 10299 return s.toString(); 10300 } 10301 key = key.toLowerCase(); 10302 return macros.containsKey(key) 10303 ? ((Map<String, Object>) macros.get(key)).get("path").toString() 10304 : null; 10305 } 10306 getInchi(BS atoms, String molData, String options)10307 public String getInchi(BS atoms, String molData, String options) { 10308 try { 10309 JmolInChI inch = this.apiPlatform.getInChI(); 10310 if (atoms == null && molData == null) 10311 return ""; 10312 if (molData != null) { 10313 if (molData.startsWith("$") || molData.startsWith(":")) { 10314 molData = getFileAsString4(molData, -1, false, false, true, "script"); 10315 } else if (!molData.startsWith("InChI=") && molData.indexOf(" ") < 0) { 10316 // assume SMILES 10317 molData = getFileAsString4("$" + molData, -1, false, false, true, 10318 "script"); 10319 } 10320 } 10321 return inch.getInchi(this, atoms, molData, options); 10322 } catch (Throwable t) { 10323 return ""; 10324 } 10325 } 10326 10327 private int consoleFontScale = 1; 10328 getConsoleFontScale()10329 public int getConsoleFontScale() { 10330 return consoleFontScale; 10331 } 10332 setConsoleFontScale(int scale)10333 public void setConsoleFontScale(int scale) { 10334 consoleFontScale = scale; 10335 } 10336 confirm(String msg, String msgNo)10337 public int confirm(String msg, String msgNo) { 10338 return apiPlatform.confirm(msg, msgNo); 10339 } 10340 } 10341