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 }