001 /*
002 * This file is part of McIDAS-V
003 *
004 * Copyright 2007-2013
005 * Space Science and Engineering Center (SSEC)
006 * University of Wisconsin - Madison
007 * 1225 W. Dayton Street, Madison, WI 53706, USA
008 * https://www.ssec.wisc.edu/mcidas
009 *
010 * All Rights Reserved
011 *
012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
013 * some McIDAS-V source code is based on IDV and VisAD source code.
014 *
015 * McIDAS-V is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser Public License as published by
017 * the Free Software Foundation; either version 3 of the License, or
018 * (at your option) any later version.
019 *
020 * McIDAS-V is distributed in the hope that it will be useful,
021 * but WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023 * GNU Lesser Public License for more details.
024 *
025 * You should have received a copy of the GNU Lesser Public License
026 * along with this program. If not, see http://www.gnu.org/licenses.
027 */
028 package edu.wisc.ssec.mcidasv;
029
030 import static ucar.unidata.util.GuiUtils.makeMenu;
031 import static ucar.unidata.util.GuiUtils.makeMenuItem;
032 import static ucar.unidata.util.MenuUtil.MENU_SEPARATOR;
033
034 import java.util.ArrayList;
035 import java.util.List;
036 import java.util.Map;
037
038 import org.python.util.PythonInterpreter;
039
040 import org.slf4j.Logger;
041 import org.slf4j.LoggerFactory;
042
043 import edu.wisc.ssec.mcidasv.util.CollectionHelpers;
044
045 import ucar.unidata.data.DataSource;
046 import ucar.unidata.data.DescriptorDataSource;
047 import ucar.unidata.idv.IntegratedDataViewer;
048 import ucar.unidata.idv.ui.ImageGenerator;
049 import ucar.unidata.idv.ui.JythonShell;
050
051 /**
052 * Overrides the IDV's {@link ucar.unidata.idv.JythonManager JythonManager} to
053 * associate a {@link JythonShell} with a given {@code JythonManager}.
054 */
055 public class JythonManager extends ucar.unidata.idv.JythonManager {
056
057 /** Trusty logging object. */
058 private static final Logger logger = LoggerFactory.getLogger(JythonManager.class);
059
060 /** Associated Jython Shell. May be {@code null}. */
061 private JythonShell jythonShell;
062
063 /**
064 * Create the manager and call initPython.
065 *
066 * @param idv The IDV.
067 */
068 public JythonManager(IntegratedDataViewer idv) {
069 super(idv);
070 }
071
072 /**
073 * Create a Jython shell, if one doesn't already exist. This will also
074 * bring the window {@literal "to the front"} of the rest of the McIDAS-V
075 * session.
076 *
077 * @return JythonShell object for interactive Jython usage.
078 */
079 public JythonShell createShell() {
080 if (jythonShell == null) {
081 jythonShell = new JythonShell(getIdv());
082
083 }
084 jythonShell.toFront();
085 return jythonShell;
086 }
087
088 /**
089 * Returns the Jython Shell associated with this {@code JythonManager}.
090 *
091 * @return Jython Shell being used by this manager. May be {@code null}.
092 */
093 public JythonShell getShell() {
094 return jythonShell;
095 }
096
097 /**
098 * Create and initialize a Jython interpreter.
099 *
100 * @return Newly created Jython interpreter.
101 */
102 @Override public PythonInterpreter createInterpreter() {
103 PythonInterpreter interpreter = super.createInterpreter();
104 return interpreter;
105 }
106
107 /**
108 * Removes the given interpreter from the list of active interpreters.
109 *
110 * <p>Also attempts to close any Jython Shell associated with the
111 * interpreter.</p>
112 *
113 * @param interpreter Interpreter to remove. Should not be {@code null}.
114 */
115 @Override public void removeInterpreter(PythonInterpreter interpreter) {
116 super.removeInterpreter(interpreter);
117 if (jythonShell != null && !jythonShell.isShellResetting() && jythonShell.getInterpreter().equals(interpreter)) {
118 jythonShell.close();
119 jythonShell = null;
120 }
121 }
122
123 /**
124 * Overridden so that McIDAS-V can inject a variable named {@code _idv}
125 * into {@code interpreter's} globals.
126 *
127 * @param interpreter Jython interpreter being initialized by the IDV. Cannot be {@code null}.
128 */
129 @Override protected void initBasicInterpreter(PythonInterpreter interpreter) {
130 interpreter.set("_idv", getIdv());
131 interpreter.set("idv", getIdv());
132 super.initBasicInterpreter(interpreter);
133 }
134
135 /**
136 * Overridden so that McIDAS-V can add an {@code islInterpreter} object
137 * to the interpreter's locals (before executing the contents of {@code}.
138 *
139 * @param code Jython code to evaluate. {@code null} is probably a bad idea.
140 * @param properties {@code String->Object} pairs to insert into the
141 * locals. Parameter may be {@code null}.
142 */
143 @SuppressWarnings("unchecked") // dealing with idv code that predates generics.
144 @Override public void evaluateTrusted(String code, Map<String, Object> properties) {
145 if (properties == null) {
146 properties = CollectionHelpers.newMap();
147 }
148 if (!properties.containsKey("islInterpreter")) {
149 properties.put("islInterpreter", new ImageGenerator(getIdv()));
150 }
151 if (!properties.containsKey("_idv")) {
152 properties.put("_idv", getIdv());
153 }
154 if (!properties.containsKey("idv")) {
155 properties.put("idv", getIdv());
156 }
157 super.evaluateTrusted(code, properties);
158 }
159
160 /**
161 * Return the list of menu items to use when the user has clicked on a
162 * formula {@link DataSource}.
163 *
164 * @param dataSource The data source clicked on.
165 *
166 * @return {@link List} of menu items.
167 */
168 @SuppressWarnings("unchecked") // dealing with idv code that predates generics.
169 @Override public List doMakeFormulaDataSourceMenuItems(DataSource dataSource) {
170 List menuItems = new ArrayList(100);
171 menuItems.add(makeMenuItem("Create Formula", this, "showFormulaDialog"));
172 List editItems;
173 if (dataSource instanceof DescriptorDataSource) {
174 editItems = doMakeEditMenuItems((DescriptorDataSource)dataSource);
175 }
176 else {
177 editItems = doMakeEditMenuItems();
178 }
179 menuItems.add(makeMenu("Edit Formulas", editItems));
180 menuItems.add(MENU_SEPARATOR);
181 menuItems.add(makeMenuItem("Jython Library", this, "showJythonEditor"));
182 menuItems.add(makeMenuItem("Jython Shell", this, "createShell"));
183 menuItems.add(MENU_SEPARATOR);
184 menuItems.add(makeMenuItem("Import", this, "importFormulas"));
185 menuItems.add(makeMenuItem("Export", this, "exportFormulas"));
186 return menuItems;
187 }
188
189 }