1 /* Copyright (c) 2002-2012 The University of the West Indies
2  *
3  * Contact: robert.lancashire@uwimona.edu.jm
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General private
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General private License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General private
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 // CHANGES to 'JSVApplet.java' - Web Application GUI
21 // University of the West Indies, Mona Campus
22 //
23 // 09-10-2007 commented out calls for exporting data
24 //            this was causing security issues with JRE 1.6.0_02 and 03
25 // 13-01-2008 in-line load JCAMP-DX file routine added
26 // 22-07-2008 reinstated calls for exporting since Ok with JRE 1.6.0_05
27 // 25-07-2008 added module to predict colour of solution
28 // 08-01-2010 need bugfix for protected static reverseplot
29 // 17-03-2010 fix for NMRShiftDB CML files
30 // 11-06-2011 fix for LINK files and reverseplot
31 // 23-07-2011 jak - Added parameters for the visibility of x units, y units,
32 //            x scale, and y scale.  Added parameteres for the font,
33 //            title font, and integral plot color.  Added a method
34 //            to reset view from a javascript call.
35 // 24-09-2011 jak - Added parameter for integration ratio annotations.
36 // 08-10-2011 jak - Add a method to toggle integration from a javascript
37 //          call. Changed behaviour to remove integration after reset
38 //          view.
39 
40 package jspecview.app;
41 
42 import java.net.URL;
43 import java.util.Map;
44 
45 import javajs.util.Lst;
46 import javajs.util.PT;
47 
48 import org.jmol.util.Logger;
49 
50 import jspecview.api.AppletFrame;
51 import jspecview.api.JSVAppInterface;
52 import jspecview.api.JSVPanel;
53 import jspecview.api.PanelListener;
54 import jspecview.api.js.JSVAppletObject;
55 import jspecview.common.Coordinate;
56 import jspecview.common.JSVFileManager;
57 import jspecview.common.JSVersion;
58 import jspecview.common.JSViewer;
59 import jspecview.common.PanelData;
60 import jspecview.common.PanelNode;
61 import jspecview.common.PeakPickEvent;
62 import jspecview.common.ScriptToken;
63 import jspecview.common.Spectrum;
64 import jspecview.common.SubSpecChangeEvent;
65 import jspecview.common.ZoomEvent;
66 import jspecview.source.JDXSource;
67 
68 /**
69  * JSpecView Applet class. For a list of parameters and scripting functionality
70  * see the file JSpecView_Applet_Specification.html.
71  *
72  * @author Bob Hanson
73  * @author Debbie-Ann Facey
74  * @author Khari A. Bryan
75  * @author Craig A. D. Walters
76  * @author Prof Robert J. Lancashire
77  */
78 
79 public class JSVApp implements PanelListener, JSVAppInterface {
80 
81 	public static final String CREDITS = "Authors:\nProf. Robert M. Hanson,\nD. Facey, K. Bryan, C. Walters, Prof. Robert J. Lancashire and\nvolunteer developers through sourceforge.";
82 
JSVApp(AppletFrame appletFrame, boolean isJS)83 	public JSVApp(AppletFrame appletFrame, boolean isJS) {
84 		this.appletFrame = appletFrame;
85 		initViewer(isJS);
86 		initParams(appletFrame.getParameter("script"));
87 	}
88 
initViewer(boolean isJS)89 	private void initViewer(boolean isJS) {
90 		vwr = new JSViewer(this, true, isJS);
91 		appletFrame.setDropTargetListener(isSigned(), vwr);
92 		URL path = appletFrame.getDocumentBase();
93 		JSVFileManager.setDocumentBase(vwr, path);
94 	}
95 
96 	protected AppletFrame appletFrame;
97 
98 	boolean isNewWindow;
99 
100 	// ------- settable parameters ------------
101 
102 	public String appletReadyCallbackFunctionName;
103 
104 	private String coordCallbackFunctionName;
105 	private String loadFileCallbackFunctionName;
106 	private String peakCallbackFunctionName;
107 	private String syncCallbackFunctionName;
108 	public JSViewer vwr;
109 
110 	// ///// parameter set/get methods
111 
112 	@Override
isPro()113 	public boolean isPro() {
114 		return isSigned();
115 	}
116 
117 	@Override
isSigned()118 	public boolean isSigned() {
119 		/**
120 		 * @j2sNative
121 		 *
122 		 * return true;
123 		 */
124 		{
125 		return false;
126 		}
127 	}
128 
getAppletFrame()129 	public AppletFrame getAppletFrame() {
130 		return appletFrame;
131 	}
132 
133 	// ///////////////////////////////////////
134 
dispose()135 	public void dispose() {
136 		try {
137 			vwr.dispose();
138 		} catch (Exception e) {
139 			e.printStackTrace();
140 		}
141 	}
142 
143 	// ///////////// private methods called from page or browser JavaScript calls
144 	// ////////////////
145 	//
146 	//
147 	// Notice that in all of these we use getSelectedPanel(), not selectedJSVPanel
148 	// That's because the methods aren't overridden in JSVAppletPro, and in that
149 	// case
150 	// we want to select the panel from MainFrame, not here. Thus, when the
151 	// Advanced...
152 	// tab is open, actions from outside of Jmol act on the MainFrame, not here.
153 	//
154 	// BH - 8.3.2012
155 
156 	@Override
getPropertyAsJavaObject(String key)157 	public Map<String, Object> getPropertyAsJavaObject(String key) {
158 		return vwr.getPropertyAsJavaObject(key);
159 	}
160 
161 	@Override
getPropertyAsJSON(String key)162 	public String getPropertyAsJSON(String key) {
163 		return PT.toJSON(null, getPropertyAsJavaObject(key));
164 	}
165 
166 	/**
167 	 * Method that can be called from another applet or from javascript to return
168 	 * the coordinate of clicked point in the plot area of the <code>
169    * JSVPanel</code>
170 	 *
171 	 * @return A String representation of the coordinate
172 	 */
173 	@Override
getCoordinate()174 	public String getCoordinate() {
175 		return vwr.getCoordinate();
176 	}
177 
178 	/**
179 	 * Loads in-line JCAMP-DX data into the existing applet window
180 	 *
181 	 * @param data
182 	 *          String
183 	 */
184 	@Override
loadInline(String data)185 	public void loadInline(String data) {
186 		// newAppletPanel();
187 		siOpenDataOrFile(data, "[inline]", null, null, -1, -1, true, null, null);
188 		appletFrame.validateContent(3);
189 	}
190 
191 	/**
192 	 * Delivers spectrum coded as desired: XY, SQZ, PAC, DIF, DIFDUP, FIX, AML,
193 	 * CML
194 	 *
195 	 * @param type
196 	 * @param n
197 	 * @return data
198 	 *
199 	 */
200 	@Override
exportSpectrum(String type, int n)201 	public String exportSpectrum(String type, int n) {
202 		return vwr.export(type, n);
203 	}
204 
205 	@Override
setFilePath(String tmpFilePath)206 	public void setFilePath(String tmpFilePath) {
207 		runScript("load " + PT.esc(tmpFilePath));
208 	}
209 
210 	/**
211 	 * Sets the spectrum to the specified block number
212 	 *
213 	 * @param n
214 	 */
215 	@Override
setSpectrumNumber(int n)216 	public void setSpectrumNumber(int n) {
217 		runScript(ScriptToken.SPECTRUMNUMBER + " " + n);
218 	}
219 
220 	/**
221 	 * Method that can be called from another applet or from javascript that
222 	 * toggles reversing the plot on a <code>JSVPanel</code>
223 	 */
224 	@Override
reversePlot()225 	public void reversePlot() {
226 		toggle(ScriptToken.REVERSEPLOT);
227 	}
228 
229 	/**
230 	 * Method that can be called from another applet or from javascript that
231 	 * toggles the grid on a <code>JSVPanel</code>
232 	 */
233 	@Override
toggleGrid()234 	public void toggleGrid() {
235 		toggle(ScriptToken.GRIDON);
236 	}
237 
238 	/**
239 	 * Method that can be called from another applet or from javascript that
240 	 * toggles the coordinate on a <code>JSVPanel</code>
241 	 */
242 	@Override
toggleCoordinate()243 	public void toggleCoordinate() {
244 		toggle(ScriptToken.COORDINATESON);
245 	}
246 
247   /**
248    * Method that can be called from another applet or from javascript that
249    * toggles the coordinate on a <code>JSVPanel</code>
250    */
251   @Override
togglePointsOnly()252   public void togglePointsOnly() {
253     toggle(ScriptToken.POINTSONLY);
254   }
255 
256 	/**
257 	 * Method that can be called from another applet or from javascript that
258 	 * toggles the integration graph of a <code>JSVPanel</code>.
259 	 */
260 	@Override
toggleIntegration()261 	public void toggleIntegration() {
262 		toggle(ScriptToken.INTEGRATE);
263 	}
264 
toggle(ScriptToken st)265 	private void toggle(ScriptToken st) {
266 		if (vwr.selectedPanel != null)
267 			runScript(st + " TOGGLE");
268 	}
269 
270 	/**
271 	 * Method that can be called from another applet or from javascript that adds
272 	 * a highlight to a portion of the plot area of a <code>JSVPanel</code>
273 	 *
274 	 * @param x1
275 	 *          the starting x value
276 	 * @param x2
277 	 *          the ending x value
278 	 * @param r
279 	 *          the red portion of the highlight color
280 	 * @param g
281 	 *          the green portion of the highlight color
282 	 * @param b
283 	 *          the blue portion of the highlight color
284 	 * @param a
285 	 *          the alpha portion of the highlight color
286 	 */
287 	@Override
addHighlight(double x1, double x2, int r, int g, int b, int a)288 	public void addHighlight(double x1, double x2, int r, int g, int b, int a) {
289 		runScript("HIGHLIGHT " + x1 + " " +x2 + " " + r + " " + g +  " " + b + " " + a);
290 	}
291 
292 	/**
293 	 * Method that can be called from another applet or from javascript that
294 	 * removes a highlight from the plot area of a <code>JSVPanel</code>
295 	 *
296 	 * @param x1
297 	 *          the starting x value
298 	 * @param x2
299 	 *          the ending x value
300 	 */
301 	@Override
removeHighlight(double x1, double x2)302 	public void removeHighlight(double x1, double x2) {
303 		runScript("HIGHLIGHT " + x1 + " " + x2 + " OFF");
304 	}
305 
306 	/**
307 	 * Method that can be called from another applet or from javascript that
308 	 * removes all highlights from the plot area of a <code>JSVPanel</code>
309 	 */
310 	@Override
removeAllHighlights()311 	public void removeAllHighlights() {
312 		runScript("HIGHLIGHT OFF");
313 	}
314 
315 	@Override
syncScript(String peakScript)316 	public void syncScript(String peakScript) {
317 		vwr.syncScript(peakScript);
318 	}
319 
320 	/**
321 	 * Writes a message to the status label
322 	 *
323 	 * @param msg
324 	 *          the message
325 	 */
326 	@Override
writeStatus(String msg)327 	public void writeStatus(String msg) {
328 		Logger.info(msg);
329 		// statusTextLabel.setText(msg);
330 	}
331 
332 	// //////////////////////// PRIVATE or SEMIPRIVATE METHODS
333 
334 	/**
335 	 * starts or restarts applet display from scratch or from a JSVApplet.script()
336 	 * JavaScript command
337 	 *
338 	 * Involves a two-pass sequence through parsing the parameters, because order
339 	 * is not important in this sort of call.
340 	 *
341 	 * To call a script and have commands execute in order, use
342 	 *
343 	 * JSVApplet.runScript(script)
344 	 *
345 	 * instead
346 	 *
347 	 * @param params
348 	 */
initParams(String params)349 	public void initParams(String params) {
350 		vwr.parseInitScript(params);
351 		newAppletPanel();
352 		vwr.setPopupMenu(vwr.allowMenu, vwr.parameters
353 				.getBoolean(ScriptToken.ENABLEZOOM));
354 		if (vwr.allowMenu) {
355 			vwr.closeSource(null);
356 		}
357 		runScriptNow(params);
358 	}
359 
newAppletPanel()360 	private void newAppletPanel() {
361 		Logger.info("newAppletPanel");
362 		appletFrame.createMainPanel(vwr);
363 	}
364 
365 	private JSVPanel prevPanel;
366 
367 	// //////////// JSVAppletPopupMenu calls
368 
369 	@Override
repaint()370   public void repaint() {
371 
372     @SuppressWarnings("unused")
373     JSVAppletObject applet = (vwr == null ? null : vwr.html5Applet);
374     if (JSViewer.jmolObject == null) {
375       appletFrame.repaint();
376     } else if (applet != null) {
377       JSViewer.jmolObject.repaint(applet, true);
378     }
379   }
380 
381 	/**
382 	 *
383 	 * @param width
384 	 * @param height
385 	 */
updateJS(int width, int height)386 	public void updateJS(int width, int height) {
387 
388 	}
389 
390 	@Override
runScriptNow(String params)391 	public boolean runScriptNow(String params) {
392 		return vwr.runScriptNow(params);
393 	}
394 
395 	/**
396 	 * fires peakCallback ONLY if there is a peak found
397 	 *
398 	 * fires coordCallback ONLY if there is no peak found or no peakCallback
399 	 * active
400 	 *
401 	 * if (peakFound && havePeakCallback) { do the peakCallback } else { do the
402 	 * coordCallback }
403 	 *
404 	 * Is that what we want?
405 	 *
406 	 */
checkCallbacks()407 	private void checkCallbacks() {
408 		if (coordCallbackFunctionName == null && peakCallbackFunctionName == null)
409 			return;
410 		Coordinate coord = new Coordinate();
411 		Coordinate actualCoord = (peakCallbackFunctionName == null ? null
412 				: new Coordinate());
413 		// will return true if actualcoord is null (just doing coordCallback)
414 		if (!vwr.pd().getPickedCoordinates(coord, actualCoord))
415 			return;
416 		int iSpec = vwr.mainPanel.getCurrentPanelIndex();
417 		if (actualCoord == null)
418 			appletFrame.callToJavaScript(coordCallbackFunctionName, new Object[] {
419 					Double.valueOf(coord.getXVal()), Double.valueOf(coord.getYVal()),
420 					Integer.valueOf(iSpec + 1) });
421 		else
422 			appletFrame
423 					.callToJavaScript(
424 							peakCallbackFunctionName,
425 							new Object[] { Double.valueOf(coord.getXVal()),
426 									Double.valueOf(coord.getYVal()),
427 									Double.valueOf(actualCoord.getXVal()),
428 									Double.valueOf(actualCoord.getYVal()),
429 									Integer.valueOf(iSpec + 1) });
430 	}
431 
432 	// /////////// MISC methods from interfaces /////////////
433 
434 	/**
435 	 * called by Pro's popup window Advanced...
436 	 *
437 	 * @param filePath
438 	 */
doAdvanced(String filePath)439 	public void doAdvanced(String filePath) {
440 		// only for JSVAppletPro
441 	}
442 
443 	// //////////////// PanelEventInterface
444 
445 	/**
446 	 * called by notifyPeakPickedListeners in JSVPanel
447 	 */
448 	@Override
panelEvent(Object eventObj)449 	public void panelEvent(Object eventObj) {
450 		if (eventObj instanceof PeakPickEvent) {
451 			vwr.processPeakPickEvent(eventObj, false);
452 		} else if (eventObj instanceof ZoomEvent) {
453 		} else if (eventObj instanceof SubSpecChangeEvent) {
454 		}
455 	}
456 
457 	/**
458 	 * Returns the calculated colour of a visible spectrum (Transmittance)
459 	 *
460 	 * @return Color
461 	 */
462 
463 	@Override
getSolnColour()464 	public String getSolnColour() {
465 		return vwr.getSolutionColorStr(true);
466 	}
467 
468   /**
469    * File has been loaded or model has been changed or atom picked.
470    * This is a call to Jmol.View for view sets (new in Jmol 14.1.8)
471    *
472    * @param msg
473    *
474    */
updateJSView(String msg)475   private void updateJSView(String msg) {
476 
477   	JSVAppletObject applet = vwr.html5Applet;
478 		JSVPanel panel = (applet == null ? null : vwr.selectedPanel);
479     /**
480      * @j2sNative
481      *
482      * applet && applet._viewSet != null && applet._updateView(panel, msg);
483      *
484      */
485     {}
486     applet._updateView(panel, msg);
487   }
488 
489 	/**
490 	 * @param msg
491 	 */
492 	@Override
syncToJmol(String msg)493 	public synchronized void syncToJmol(String msg) {
494 		updateJSView(msg);
495 		if (syncCallbackFunctionName == null)
496 			return;
497 		Logger.info("JSVApp.syncToJmol JSV>Jmol " + msg);
498 		appletFrame.callToJavaScript(syncCallbackFunctionName, new Object[] { vwr.fullName, msg });
499 	}
500 
501 	@Override
setVisible(boolean b)502 	public void setVisible(boolean b) {
503 		appletFrame.setPanelVisible(b);
504 	}
505 
506 	@Override
setCursor(int id)507 	public void setCursor(int id) {
508 		vwr.apiPlatform.setCursor(id, appletFrame);
509 	}
510 
511 	@Override
runScript(String script)512 	public void runScript(String script) {
513 		vwr.runScript(script);
514 	}
515 
516 	@Override
getScriptQueue()517 	public Lst<String> getScriptQueue() {
518 		return vwr.scriptQueue;
519 	}
520 
521 
522 	// ///////////// JSApp/MainFrame ScriptInterface /////////////
523 
524 	@Override
siSetCurrentSource(JDXSource source)525 	public void siSetCurrentSource(JDXSource source) {
526 		vwr.currentSource = source;
527 	}
528 
529 	@Override
siSendPanelChange()530 	public void siSendPanelChange() {
531 		if (vwr.selectedPanel == prevPanel)
532 			return;
533 		prevPanel = vwr.selectedPanel;
534 		vwr.sendPanelChange();
535 	}
536 
537 	/**
538 	 * Shows the applet in a Frame
539 	 *
540 	 * @param isSelected
541 	 */
542 	@Override
siNewWindow(boolean isSelected, boolean fromFrame)543 	public void siNewWindow(boolean isSelected, boolean fromFrame) {
544 		isNewWindow = isSelected;
545 		if (fromFrame) {
546 			if (vwr.jsvpPopupMenu != null)
547 				vwr.jsvpPopupMenu.setSelected("Window", false);
548 		} else {
549 			appletFrame.newWindow(isSelected);
550 		}
551 	}
552 
553 	@Override
siValidateAndRepaint(boolean isAll)554 	public void siValidateAndRepaint(boolean isAll) {
555 		PanelData pd = vwr.pd();
556 		if (pd != null)
557 			pd.setTaintedAll();
558 		appletFrame.validate();
559 		repaint();
560 	}
561 
562 	/**
563 	 * Loads a new file into the existing applet window
564 	 *
565 	 * @param filePath
566 	 */
567 	@Override
siSyncLoad(String filePath)568 	public void siSyncLoad(String filePath) {
569 		newAppletPanel();
570 		Logger.info("JSVP syncLoad reading " + filePath);
571 		siOpenDataOrFile(null, null, null, filePath, -1, -1, false, null, null);
572 		appletFrame.validateContent(3);
573 	}
574 
575 	/*
576 	 * private void interruptQueueThreads() { if (commandWatcherThread != null)
577 	 * commandWatcherThread.interrupt(); }
578 	 */
579 	@Override
siOpenDataOrFile(Object data, String name, Lst<Spectrum> specs, String url, int firstSpec, int lastSpec, boolean isAppend, String script, String id)580 	public void siOpenDataOrFile(Object data, String name,
581 			Lst<Spectrum> specs, String url, int firstSpec, int lastSpec,
582 			boolean isAppend, String script, String id) {
583 		switch (vwr.openDataOrFile(data, name, specs, url, firstSpec, lastSpec,
584 				isAppend, id)) {
585 		case JSViewer.FILE_OPEN_OK:
586 			if (script != null)
587 				runScript(script);
588 			break;
589 		case JSViewer.FILE_OPEN_ALREADY:
590 			return;
591 		default:
592 			siSetSelectedPanel(null);
593 			return;
594 		}
595 
596 		// not implemented
597 //		if (vwr.jsvpPopupMenu != null)
598 //			vwr.jsvpPopupMenu
599 //					.setCompoundMenu(vwr.panelNodes, vwr.allowCompoundMenu);
600 
601 		Logger.info(appletFrame.getAppletInfo() + " File "
602 				+ vwr.currentSource.getFilePath() + " Loaded Successfully");
603 
604 	}
605 
606 	/**
607 	 * overloaded in JSVAppletPro
608 	 *
609 	 * @param scriptItem
610 	 */
611 	@Override
siProcessCommand(String scriptItem)612 	public void siProcessCommand(String scriptItem) {
613 		vwr.runScriptNow(scriptItem);
614 	}
615 
616 	@Override
siSetSelectedPanel(JSVPanel jsvp)617 	public void siSetSelectedPanel(JSVPanel jsvp) {
618 		vwr.mainPanel.setSelectedPanel(vwr, jsvp, vwr.panelNodes);
619 		vwr.selectedPanel = jsvp;
620 		vwr.spectraTree.setSelectedPanel(this, jsvp);
621 		if (jsvp == null) {
622 			vwr.selectedPanel = jsvp = appletFrame.getJSVPanel(vwr, null);
623 			vwr.mainPanel.setSelectedPanel(vwr, jsvp, null);
624 		}
625 		appletFrame.validate();
626 		if (jsvp != null) {
627 			jsvp.setEnabled(true);
628 			jsvp.setFocusable(true);
629 		}
630 	}
631 
632 	@Override
633 	@SuppressWarnings("incomplete-switch")
siExecSetCallback(ScriptToken st, String value)634 	public void siExecSetCallback(ScriptToken st, String value) {
635 		switch (st) {
636 		case APPLETREADYCALLBACKFUNCTIONNAME:
637 			appletReadyCallbackFunctionName = value;
638 			break;
639 		case LOADFILECALLBACKFUNCTIONNAME:
640 			loadFileCallbackFunctionName = value;
641 			break;
642 		case PEAKCALLBACKFUNCTIONNAME:
643 			peakCallbackFunctionName = value;
644 			break;
645 		case SYNCCALLBACKFUNCTIONNAME:
646 			syncCallbackFunctionName = value;
647 			break;
648 		case COORDCALLBACKFUNCTIONNAME:
649 			coordCallbackFunctionName = value;
650 			break;
651 		}
652 	}
653 
654 	@Override
siLoaded(String value)655 	public String siLoaded(String value) {
656 		if (loadFileCallbackFunctionName != null)
657 			appletFrame.callToJavaScript(loadFileCallbackFunctionName, new Object[] { vwr.appletName,
658 					value });
659 		updateJSView(null);
660 		return null;
661 	}
662 
663 
664 	@Override
siExecHidden(boolean b)665 	public void siExecHidden(boolean b) {
666 		// ignored
667 	}
668 
669 	@Override
siExecScriptComplete(String msg, boolean isOK)670 	public void siExecScriptComplete(String msg, boolean isOK) {
671 	  if (!isOK)
672 	  	vwr.showMessage(msg);
673 		siValidateAndRepaint(false);
674 	}
675 
676 	@Override
siUpdateBoolean(ScriptToken st, boolean TF)677 	public void siUpdateBoolean(ScriptToken st, boolean TF) {
678 		// ignored -- this is for setting buttons and menu items
679 	}
680 
681 	@Override
siCheckCallbacks(String title)682 	public void siCheckCallbacks(String title) {
683 		checkCallbacks();
684 	}
685 
686 	// /////// multiple source changes ////////
687 
688 	@Override
siNodeSet(PanelNode panelNode)689 	public void siNodeSet(PanelNode panelNode) {
690 		appletFrame.validateContent(2);
691 		siValidateAndRepaint(false); // app does not do repaint here
692 	}
693 
694 	@Override
siSourceClosed(JDXSource source)695 	public void siSourceClosed(JDXSource source) {
696 		// n/a;
697 	}
698 
699 	@Override
siGetNewJSVPanel(Spectrum spec)700 	public JSVPanel siGetNewJSVPanel(Spectrum spec) {
701 		if (spec == null) {
702 			vwr.initialEndIndex = vwr.initialStartIndex = -1;
703 			return null;
704 		}
705 		Lst<Spectrum> specs = new Lst<Spectrum>();
706 		specs.addLast(spec);
707 		JSVPanel jsvp = appletFrame.getJSVPanel(vwr, specs);
708 		jsvp.getPanelData().addListener(this);
709 		vwr.parameters.setFor(jsvp, null, true);
710 		return jsvp;
711 	}
712 
713 	@Override
siGetNewJSVPanel2(Lst<Spectrum> specs)714 	public JSVPanel siGetNewJSVPanel2(Lst<Spectrum> specs) {
715 		if (specs == null) {
716 			vwr.initialEndIndex = vwr.initialStartIndex = -1;
717 			return appletFrame.getJSVPanel(vwr, null);
718 		}
719 		JSVPanel jsvp = appletFrame.getJSVPanel(vwr, specs);
720 		vwr.initialEndIndex = vwr.initialStartIndex = -1;
721 		jsvp.getPanelData().addListener(this);
722 		vwr.parameters.setFor(jsvp, null, true);
723 		return jsvp;
724 	}
725 
726 	@Override
siSetPropertiesFromPreferences(JSVPanel jsvp, boolean includeMeasures)727 	public void siSetPropertiesFromPreferences(JSVPanel jsvp,
728 			boolean includeMeasures) {
729 		vwr.checkAutoIntegrate();
730 	}
731 
732 	// not applicable to applet:
733 
734 	@Override
siSetLoaded(String fileName, String filePath)735 	public void siSetLoaded(String fileName, String filePath) {
736 		//n/a
737 	}
738 
739 	@Override
siSetMenuEnables(PanelNode node, boolean isSplit)740 	public void siSetMenuEnables(PanelNode node, boolean isSplit) {
741 	}
742 
743 	@Override
siUpdateRecentMenus(String filePath)744 	public void siUpdateRecentMenus(String filePath) {
745 	}
746 
747 	@Override
siExecTest(String value)748 	public void siExecTest(String value) {
749 	  String data = "";//##TITLE= Acetophenone\n##JCAMP-DX= 5.01\n##DATA TYPE= MASS SPECTRUM\n##DATA CLASS= XYPOINTS\n##ORIGIN= UWI, Mona, JAMAICA\n##OWNER= public domain\n##LONGDATE= 2012/02/19 22:20:06.0416 -0600 $$ export date from JSpecView\n##BLOCK_ID= 4\n##$URL= http://wwwchem.uwimona.edu.jm/spectra\n##SPECTROMETER/DATA SYSTEM= Finnigan\n##.INSTRUMENT PARAMETERS= LOW RESOLUTION\n##.SPECTROMETER TYPE= TRAP\n##.INLET= GC\n##.IONIZATION MODE= EI+\n##MOLFORM= C 8 H 8 O\n##$MODELS= \n<Models>\n<ModelData id=\"acetophenone\" type=\"MOL\">\nacetophenone\nDSViewer          3D                             0\n\n17 17  0  0  0  0  0  0  0  0999 V2000\n-1.6931    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  1\n-0.2141    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  2\n2.5839    0.0872    0.0000 C   0  0  0  0  0  0  0  0  0  3\n0.4615    1.2373   -0.0005 C   0  0  0  0  0  0  0  0  0  4\n0.5257   -1.1809    0.0001 C   0  0  0  0  0  0  0  0  0  5\n1.9188   -1.1393    0.0005 C   0  0  0  0  0  0  0  0  0  6\n1.8539    1.2756   -0.0001 C   0  0  0  0  0  0  0  0  0  7\n-0.1262    2.1703   -0.0009 H   0  0  0  0  0  0  0  0  0  8\n0.0144   -2.1556    0.0002 H   0  0  0  0  0  0  0  0  0  9\n2.4947   -2.0764    0.0009 H   0  0  0  0  0  0  0  0  0 10\n2.3756    2.2439   -0.0001 H   0  0  0  0  0  0  0  0  0 11\n3.6838    0.1161    0.0003 H   0  0  0  0  0  0  0  0  0 12\n-2.3403    1.0639    0.0008 O   0  0  0  0  0  0  0  0  0 13\n-2.3832   -1.3197   -0.0010 C   0  0  0  0  0  0  0  0  0 14\n-2.0973   -1.8988    0.9105 H   0  0  0  0  0  0  0  0  0 15\n-2.0899   -1.9018   -0.9082 H   0  0  0  0  0  0  0  0  0 16\n-3.4920   -1.1799   -0.0059 H   0  0  0  0  0  0  0  0  0 17\n1  2  1  0  0  0\n2  5  4  0  0  0\n2  4  4  0  0  0\n3 12  1  0  0  0\n4  7  4  0  0  0\n5  6  4  0  0  0\n6 10  1  0  0  0\n6  3  4  0  0  0\n7  3  4  0  0  0\n7 11  1  0  0  0\n8  4  1  0  0  0\n9  5  1  0  0  0\n13  1  2  0  0  0\n14 16  1  0  0  0\n14  1  1  0  0  0\n14 15  1  0  0  0\n17 14  1  0  0  0\nM  END\n</ModelData>\n<ModelData id=\"2\" type=\"MOL\">\nacetophenone m/z 120\nDSViewer          3D                             0\n\n17 17  0  0  0  0  0  0  0  0999 V2000\n-1.6931    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  1\n-0.2141    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  2\n2.5839    0.0872    0.0000 C   0  0  0  0  0  0  0  0  0  3\n0.4615    1.2373   -0.0005 C   0  0  0  0  0  0  0  0  0  4\n0.5257   -1.1809    0.0001 C   0  0  0  0  0  0  0  0  0  5\n1.9188   -1.1393    0.0005 C   0  0  0  0  0  0  0  0  0  6\n1.8539    1.2756   -0.0001 C   0  0  0  0  0  0  0  0  0  7\n-0.1262    2.1703   -0.0009 H   0  0  0  0  0  0  0  0  0  8\n0.0144   -2.1556    0.0002 H   0  0  0  0  0  0  0  0  0  9\n2.4947   -2.0764    0.0009 H   0  0  0  0  0  0  0  0  0 10\n2.3756    2.2439   -0.0001 H   0  0  0  0  0  0  0  0  0 11\n3.6838    0.1161    0.0003 H   0  0  0  0  0  0  0  0  0 12\n-2.3403    1.0639    0.0008 O   0  0  0  0  0  0  0  0  0 13\n-2.3832   -1.3197   -0.0010 C   0  0  0  0  0  0  0  0  0 14\n-2.0973   -1.8988    0.9105 H   0  0  0  0  0  0  0  0  0 15\n-2.0899   -1.9018   -0.9082 H   0  0  0  0  0  0  0  0  0 16\n-3.4920   -1.1799   -0.0059 H   0  0  0  0  0  0  0  0  0 17\n1  2  1  0  0  0\n2  5  4  0  0  0\n2  4  4  0  0  0\n3 12  1  0  0  0\n4  7  4  0  0  0\n5  6  4  0  0  0\n6 10  1  0  0  0\n6  3  4  0  0  0\n7  3  4  0  0  0\n7 11  1  0  0  0\n8  4  1  0  0  0\n9  5  1  0  0  0\n13  1  2  0  0  0\n14 16  1  0  0  0\n14  1  1  0  0  0\n14 15  1  0  0  0\n17 14  1  0  0  0\nM  END\nacetophenone m/z 105\n\ncreated with ArgusLab version 4.0.1\n13 13  0  0  0  0  0  0  0  0  0 V2000\n-1.6931    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n-0.2141    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n2.5839    0.0872    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n0.4615    1.2373   -0.0005 C   0  0  0  0  0  0  0  0  0  0  0  0\n0.5257   -1.1809    0.0001 C   0  0  0  0  0  0  0  0  0  0  0  0\n1.9188   -1.1393    0.0005 C   0  0  0  0  0  0  0  0  0  0  0  0\n1.8539    1.2756   -0.0001 C   0  0  0  0  0  0  0  0  0  0  0  0\n-2.3403    1.0639    0.0008 O   0  0  0  0  0  0  0  0  0  0  0  0\n-0.1262    2.1703   -0.0009 H   0  0  0  0  0  0  0  0  0  0  0  0\n0.0144   -2.1556    0.0002 H   0  0  0  0  0  0  0  0  0  0  0  0\n2.4947   -2.0764    0.0009 H   0  0  0  0  0  0  0  0  0  0  0  0\n2.3756    2.2439   -0.0001 H   0  0  0  0  0  0  0  0  0  0  0  0\n3.6838    0.1161    0.0003 H   0  0  0  0  0  0  0  0  0  0  0  0\n1  2  1  0  0  0  0\n1  8  2  0  0  0  0\n2  4  4  0  0  0  0\n2  5  4  0  0  0  0\n3  6  4  0  0  0  0\n3  7  4  0  0  0  0\n3 13  1  0  0  0  0\n4  7  4  0  0  0  0\n4  9  1  0  0  0  0\n5  6  4  0  0  0  0\n5 10  1  0  0  0  0\n6 11  1  0  0  0  0\n7 12  1  0  0  0  0\nM  END\nacetophenone m/z 77\n\ncreated with ArgusLab version 4.0.1\n11 11  0  0  0  0  0  0  0  0  0 V2000\n-0.2141    0.0078    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n2.5839    0.0872    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n0.4615    1.2373   -0.0005 C   0  0  0  0  0  0  0  0  0  0  0  0\n0.5257   -1.1809    0.0001 C   0  0  0  0  0  0  0  0  0  0  0  0\n1.9188   -1.1393    0.0005 C   0  0  0  0  0  0  0  0  0  0  0  0\n1.8539    1.2756   -0.0001 C   0  0  0  0  0  0  0  0  0  0  0  0\n-0.1262    2.1703   -0.0009 H   0  0  0  0  0  0  0  0  0  0  0  0\n0.0144   -2.1556    0.0002 H   0  0  0  0  0  0  0  0  0  0  0  0\n2.4947   -2.0764    0.0009 H   0  0  0  0  0  0  0  0  0  0  0  0\n2.3756    2.2439   -0.0001 H   0  0  0  0  0  0  0  0  0  0  0  0\n3.6838    0.1161    0.0003 H   0  0  0  0  0  0  0  0  0  0  0  0\n1  3  4  0  0  0  0\n1  4  4  0  0  0  0\n2  5  4  0  0  0  0\n2  6  4  0  0  0  0\n2 11  1  0  0  0  0\n3  6  4  0  0  0  0\n3  7  1  0  0  0  0\n4  5  4  0  0  0  0\n4  8  1  0  0  0  0\n5  9  1  0  0  0  0\n6 10  1  0  0  0  0\nM  END\n</ModelData>\n</Models>\n##$PEAKS= \n<Peaks type=\"MS\" xUnits=\"M/Z\" yUnits=\"RELATIVE ABUNDANCE\" >\n<PeakData id=\"1\" title=\"molecular ion (~120)\" peakShape=\"sharp\" model=\"2.1\"  xMax=\"121\" xMin=\"119\"  yMax=\"100\" yMin=\"0\" />\n<PeakData id=\"2\" title=\"fragment 1 (~105)\" peakShape=\"sharp\" model=\"2.2\"  xMax=\"106\" xMin=\"104\"  yMax=\"100\" yMin=\"0\" />\n<PeakData id=\"3\" title=\"fragment 2 (~77)\" peakShape=\"sharp\" model=\"2.3\"  xMax=\"78\" xMin=\"76\"  yMax=\"100\" yMin=\"0\" />\n</Peaks>\n##XUNITS= M/Z\n##YUNITS= RELATIVE ABUNDANCE\n##XFACTOR= 1E0\n##YFACTOR= 1E0\n##FIRSTX= 0\n##FIRSTY= 0\n##LASTX= 121\n##NPOINTS= 19\n##XYPOINTS= (XY..XY)\n0.000000, 0.000000 \n38.000000, 5.200000 \n39.000000, 8.000000 \n43.000000, 21.900000 \n50.000000, 20.200000 \n51.000000, 41.900000 \n52.000000, 4.000000 \n63.000000, 3.800000 \n74.000000, 6.600000 \n75.000000, 3.700000 \n76.000000, 4.600000 \n77.000000, 100.000000 \n78.000000, 10.400000 \n89.000000, 1.000000 \n91.000000, 1.000000 \n105.000000, 80.800000 \n106.000000, 6.000000 \n120.000000, 23.100000 \n121.000000, 2.000000 \n##END=";
750 		loadInline(data);
751 	}
752 
753 	@Override
print(String fileName)754 	public String print(String fileName) {
755 		return vwr.print(fileName);
756 	}
757 
758 	@Override
checkScript(String script)759   public String checkScript(String script) {
760 		return vwr.checkScript(script);
761 	}
762 
getAppletInfo()763 	public static String getAppletInfo() {
764 		return "JSpecView Applet " + JSVersion.VERSION + "\n\n" + CREDITS;
765 	}
766 
767 }
768