Revision: 20309 http://sourceforge.net/p/jmol/code/20309 Author: hansonr Date: 2015-02-22 05:47:23 +0000 (Sun, 22 Feb 2015) Log Message: ----------- Jmol.___JmolVersion="14.3.12_2015.02.21"
new feature: Windows BMP image reading new feature: (application only) show IMAGE -- pops up a frame with the current image new feature: (application only) show IMAGE "filename" -- pops up a frame with the image loaded from a file code: javajs.img.bMPDecoder code: org.openscience.jmol.app.jmolpanel.ImageDialog Modified Paths: -------------- trunk/Jmol/src/javajs/api/GenericImageEncoder.java trunk/Jmol/src/javajs/img/JpgEncoder.java trunk/Jmol/src/javajs/img/PngEncoder.java trunk/Jmol/src/org/jmol/awt/Image.java trunk/Jmol/src/org/jmol/awt/Platform.java trunk/Jmol/src/org/jmol/c/CBK.java trunk/Jmol/src/org/jmol/console/GenericConsole.java trunk/Jmol/src/org/jmol/io/JmolUtil.java trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java trunk/Jmol/src/org/jmol/scriptext/CmdExt.java trunk/Jmol/src/org/jmol/util/GenericApplet.java trunk/Jmol/src/org/jmol/viewer/FileManager.java trunk/Jmol/src/org/jmol/viewer/Jmol.properties trunk/Jmol/src/org/jmol/viewer/OutputManager.java trunk/Jmol/src/org/jmol/viewer/StatusManager.java trunk/Jmol/src/org/jmol/viewer/Viewer.java trunk/Jmol/src/org/molecularplayground/MPJmolApp.java trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/GuiMap.java trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/JmolPanel.java trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/NBODialog.java trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/Properties/Jmol-resources.properties trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/StatusListener.java Added Paths: ----------- trunk/Jmol/src/javajs/img/BMPDecoder.java trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/ImageDialog.java Modified: trunk/Jmol/src/javajs/api/GenericImageEncoder.java =================================================================== --- trunk/Jmol/src/javajs/api/GenericImageEncoder.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/javajs/api/GenericImageEncoder.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -8,4 +8,5 @@ public boolean createImage(String type, OC out, Map<String, Object> params) throws Exception; + } Added: trunk/Jmol/src/javajs/img/BMPDecoder.java =================================================================== --- trunk/Jmol/src/javajs/img/BMPDecoder.java (rev 0) +++ trunk/Jmol/src/javajs/img/BMPDecoder.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -0,0 +1,192 @@ +/* $RCSfile$ + * $Author: nicove $ + * $Date: 2007-03-30 12:26:16 -0500 (Fri, 30 Mar 2007) $ + * $Revision: 7275 $ + * + * Copyright (C) 2002-2005 The Jmol Development Team + * + * Contact: jmol-develop...@lists.sf.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +package javajs.img; + +import java.io.BufferedInputStream; +import java.io.IOException; + +import javajs.util.Rdr; + +/** + * src: http://www.javaworld.com/article/2077542/learn-java/java-tip-43--how-to- + * read-8--and-24-bit-microsoft-windows-bitmaps-in-java-applications.html + * + * see also: http://en.wikipedia.org/wiki/BMP_file_format + * + * Modified by Bob Hanson hans...@stolaf.edu + * + * @author Bob Hanson (hans...@stolaf.edu) + * + */ +public class BMPDecoder { + + public BMPDecoder() { + // for reflection + } + + private BufferedInputStream bis; + + /** + * original comment: + * + * loadbitmap() method converted from Windows C code. Reads only uncompressed + * 24- and 8-bit images. Tested with images saved using Microsoft Paint in + * Windows 95. If the image is not a 24- or 8-bit image, the program refuses + * to even try. I guess one could include 4-bit images by masking the byte by + * first 1100 and then 0011. I am not really interested in such images. If a + * compressed image is attempted, the routine will probably fail by generating + * an IOException. Look for variable ncompression to be different from 0 to + * indicate compression is present. + * + * @param bytes + * @return [image byte array, width, height] + */ + public Object[] decodeWindowsBMP(byte[] bytes) { + try { + bis = Rdr.getBIS(bytes); + temp = new byte[4]; + // read BITMAPFILEHEADER + if (readByte() != 'B' || readByte() != 'M') + return null; + readInt(); // file size; ignored + readShort(); // reserved + readShort(); // reserved + readInt(); // ptr to pixel array; ignored + int imageWidth, imageHeight, bitsPerPixel, nColors = 0, imageSize = 0; + // read BITMAP header + int headerSize = readInt(); + switch (headerSize) { + case 12: + // BITMAPCOREHEADER + imageWidth = readShort(); + imageHeight = readShort(); + readShort(); // planes + bitsPerPixel = readShort(); + break; + case 40: + // BITMAPINFOHEADER + imageWidth = readInt(); + imageHeight = readInt(); + readShort(); // planes + bitsPerPixel = readShort(); + int ncompression = readInt(); + if (ncompression != 0) { + System.out.println("BMP Compression is :" + ncompression + + " -- aborting"); + return null; + } + imageSize = readInt(); + readInt(); // hres + readInt(); // vres + nColors = readInt(); + readInt(); // colors used + break; + default: + System.out.println("BMP Header unrecognized, length=" + headerSize + + " -- aborting"); + return null; + } + int nPixels = imageHeight * imageWidth; + int nread = bitsPerPixel / 8; + int npad = (imageSize == 0 ? 4 - (imageWidth % 4) + : (imageSize / imageHeight) - imageWidth * nread) % 4; + int[] buf = new int[nPixels]; + switch (bitsPerPixel) { + case 32: + case 24: + for (int pt = nPixels - imageWidth; pt >= 0; pt -= imageWidth) { + for (int i = 0; i < imageWidth; i++) + buf[pt + i] = readColor(nread); + for (int i = 0; i < npad; i++) + readByte(); + } + break; + case 8: + nColors = (nColors > 0 ? nColors : 1 << bitsPerPixel); + int[] palette = new int[nColors]; + for (int i = 0; i < nColors; i++) + palette[i] = readColor(4); + for (int pt = nPixels - imageWidth; pt >= 0; pt -= imageWidth) { + for (int i = 0; i < imageWidth; i++) + buf[pt + i] = palette[readByte()]; + for (int i = 0; i < npad; i++) + readByte(); + } + break; + case 1: + int color1 = readColor(3); + int color2 = readColor(3); + npad = (4 - (((imageWidth + 7) / 8) % 4)) % 4; + int b = 0; + for (int pt = nPixels - imageWidth; pt >= 0; pt -= imageWidth) { + for (int i = 0, bpt = -1; i < imageWidth; i++, bpt--) { + if (bpt < 0) { + b = readByte(); + bpt = 7; + } + buf[pt + i] = ((b & (1 << bpt)) == 0 ? color1 + : color2); + } + for (int i = 0; i < npad; i++) + readByte(); + } + break; + default: + System.out + .println("Not a 32-, 24-, 8-, or 1-bit Windows Bitmap, aborting..."); + return null; + } + return new Object[] { buf, Integer.valueOf(imageWidth), + Integer.valueOf(imageHeight) }; + } catch (Exception e) { + System.out.println("Caught exception in loadbitmap!"); + } + return null; + } + + private byte[] temp; + + private int readColor(int n) throws IOException { + bis.read(temp, 0, n); + return 0xff << 24 | ((temp[2] & 0xff) << 16) + | ((temp[1] & 0xff) << 8) | temp[0] & 0xff; + } + + private int readInt() throws IOException { + bis.read(temp, 0, 4); + return ((temp[3] & 0xff) << 24) | ((temp[2] & 0xff) << 16) + | ((temp[1] & 0xff) << 8) | temp[0] & 0xff; + } + + private int readShort() throws IOException { + bis.read(temp, 0, 2); + return ((temp[1] & 0xff) << 8) | temp[0] & 0xff; + } + + private int readByte() throws IOException { + bis.read(temp, 0, 1); + return temp[0] & 0xff; + } + +} Property changes on: trunk/Jmol/src/javajs/img/BMPDecoder.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Modified: trunk/Jmol/src/javajs/img/JpgEncoder.java =================================================================== --- trunk/Jmol/src/javajs/img/JpgEncoder.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/javajs/img/JpgEncoder.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -75,7 +75,7 @@ @Override protected void setParams(Map<String, Object> params) { if (quality <= 0) - quality = defaultQuality; + quality = (params.containsKey("qualityJPG") ? ((Integer) params.get("qualityJPG")).intValue() : defaultQuality); jpegObj = new JpegObj(); jpegObj.comment = (String) params.get("comment"); applicationTag = (String) params.get("jpgAppTag"); Modified: trunk/Jmol/src/javajs/img/PngEncoder.java =================================================================== --- trunk/Jmol/src/javajs/img/PngEncoder.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/javajs/img/PngEncoder.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -112,8 +112,9 @@ @Override protected void setParams(Map<String, Object> params) { if (quality < 0) - quality = 2; - else if (quality > 9) + quality = (params.containsKey("qualityPNG") ? ((Integer) params + .get("qualityPNG")).intValue() : 2); + if (quality > 9) quality = 9; encodeAlpha = false; filter = FILTER_NONE; Modified: trunk/Jmol/src/org/jmol/awt/Image.java =================================================================== --- trunk/Jmol/src/org/jmol/awt/Image.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/awt/Image.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -37,17 +37,20 @@ import java.awt.image.DataBuffer; import java.awt.image.DirectColorModel; import java.awt.image.DataBufferInt; +import java.awt.image.MemoryImageSource; import java.awt.image.PixelGrabber; import java.awt.image.Raster; import java.awt.image.SinglePixelPackedSampleModel; import java.net.URL; import javajs.api.PlatformViewer; +import javajs.img.BMPDecoder; import javajs.util.AU; import javajs.util.PT; import javax.swing.JPanel; +import org.jmol.api.Interface; import org.jmol.viewer.Viewer; /** @@ -58,7 +61,7 @@ */ class Image { - static Object createImage(Object data) { + static Object createImage(Object data, PlatformViewer vwr) { if (data instanceof URL) return Toolkit.getDefaultToolkit().createImage((URL) data); if (data instanceof String) @@ -66,12 +69,26 @@ if (PT.isAB(data)) { // for the SUN processor, we need to fix the CRC byte[] b = (byte[]) data; - if (b.length > 53 && b[51] == 32 && b[52] == 78 && b[53] == 71) { //<space>NG + if (b.length < 3) + return null; + if (b[0] == 'B' && b[1] == 'M') { + // Windows BMP file + Component c = ((Component) ((Viewer) vwr).display); + if (c == null) + return null; + BMPDecoder ie = (BMPDecoder) Interface.getInterface( + "javajs.img.BMPDecoder", (Viewer) vwr, "createImage"); + Object[] o = ie.decodeWindowsBMP(b); + if (o == null || o[0] == null) + return null; + int w = ((Integer) o[1]).intValue(); + int h = ((Integer) o[2]).intValue(); + return c.createImage(new MemoryImageSource(w, h, (int[]) o[0], 0, w)); + } else if (b.length > 53 && b[51] == 32 && b[52] == 78 && b[53] == 71) { //<space>NG b = AU.arrayCopyByte(b, -1); b[51] = 80; // P } return Toolkit.getDefaultToolkit().createImage(b); - } return null; } Modified: trunk/Jmol/src/org/jmol/awt/Platform.java =================================================================== --- trunk/Jmol/src/org/jmol/awt/Platform.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/awt/Platform.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -123,7 +123,7 @@ */ @Override public Object createImage(Object data) { - return Image.createImage(data); + return Image.createImage(data, vwr); } @Override Modified: trunk/Jmol/src/org/jmol/c/CBK.java =================================================================== --- trunk/Jmol/src/org/jmol/c/CBK.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/c/CBK.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -38,6 +38,7 @@ ERROR, EVAL, HOVER, + IMAGE, LOADSTRUCT, MEASURE, MESSAGE, Modified: trunk/Jmol/src/org/jmol/console/GenericConsole.java =================================================================== --- trunk/Jmol/src/org/jmol/console/GenericConsole.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/console/GenericConsole.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -300,6 +300,7 @@ case ERROR: case EVAL: case HOVER: + case IMAGE: case LOADSTRUCT: case MINIMIZATION: case SERVICE: Modified: trunk/Jmol/src/org/jmol/io/JmolUtil.java =================================================================== --- trunk/Jmol/src/org/jmol/io/JmolUtil.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/io/JmolUtil.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -693,7 +693,8 @@ boolean createImage = false; String fullPathName = "" + fullPathNameOrBytes; if (fullPathNameOrBytes instanceof String) { - if (fullPathName.indexOf("|") > 0) { + boolean isBMP = fullPathName.toUpperCase().endsWith("BMP"); + if (fullPathName.indexOf("|") > 0 || isBMP) { Object ret = vwr.fm.getFileAsBytes(fullPathName, null); if (!PT.isAB(ret)) return "" + ret; Modified: trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java =================================================================== --- trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/script/ScriptMathProcessor.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -947,6 +947,11 @@ // special flag to get all properties. return (x2.tok == T.bitset && (chk ? addXStr("") : getAllProperties(x2, (String) op.value))); + case T.type: + return addXStr(typeOf(x2)); + case T.keys: + return getKeys(x2, (op.intValue & T.minmaxmask) == T.minmaxmask); + case T.length: case T.count: case T.size: if (iv == T.length && x2.value instanceof BondSet) Modified: trunk/Jmol/src/org/jmol/scriptext/CmdExt.java =================================================================== --- trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/scriptext/CmdExt.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -3283,6 +3283,10 @@ type = (fileName != null && fileName.indexOf(".") >= 0 ? fileName .substring(fileName.lastIndexOf(".") + 1).toUpperCase() : "XYZ"); isImage = PT.isOneOf(type.toLowerCase(), JC.IMAGE_OR_SCENE); + if (isImage && isShow && fileName == null) { + isShow = false; + fileName = "\1write " + type; + } if (scripts != null) { if (type.equals("PNG")) type = "PNGJ"; @@ -3583,6 +3587,14 @@ if (!chk) msg = ((SV) eval.theToken).escape(); break; + case T.image: + eval.checkLength23(); + len = st.length; + String fileName = eval.optParameterAsString(2); + if (!chk) + vwr.fm.loadImage(fileName, "\1" + fileName); + str = null; + break; case T.domains: eval.checkLength23(); len = st.length; Modified: trunk/Jmol/src/org/jmol/util/GenericApplet.java =================================================================== --- trunk/Jmol/src/org/jmol/util/GenericApplet.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/util/GenericApplet.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -575,6 +575,7 @@ case DRAGDROP: case ERROR: case EVAL: + case IMAGE: case LOADSTRUCT: case SCRIPT: return !isJNLP; @@ -609,6 +610,7 @@ case ERROR: case EVAL: case HOVER: + case IMAGE: case MINIMIZATION: case SERVICE: case RESIZE: Modified: trunk/Jmol/src/org/jmol/viewer/FileManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/FileManager.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/viewer/FileManager.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -903,23 +903,24 @@ String nameOrError = null; byte[] bytes = null; if (nameOrBytes instanceof Map) { - if (((Map<String, Object>) nameOrBytes).containsKey("_DATA_")) - nameOrBytes = ((Map<String, Object>) nameOrBytes).get("_DATA_"); - else - nameOrBytes = ((Map<String, Object>) nameOrBytes).get("_IMAGE_"); - } if (nameOrBytes instanceof SV) + nameOrBytes = (((Map<String, Object>) nameOrBytes).containsKey("_DATA_") ? ((Map<String, Object>) nameOrBytes) + .get("_DATA_") : ((Map<String, Object>) nameOrBytes).get("_IMAGE_")); + } + if (nameOrBytes instanceof SV) nameOrBytes = ((SV) nameOrBytes).value; String name = (nameOrBytes instanceof String ? (String) nameOrBytes : null); if (name != null && name.startsWith(";base64,")) { bytes = Base64.decodeBase64(name); } else if (nameOrBytes instanceof BArray) { bytes = ((BArray) nameOrBytes).data; - } else { + } else if (echoName == null || nameOrBytes instanceof String){ String[] names = getClassifiedName((String) nameOrBytes, true); nameOrError = (names == null ? "cannot read file name: " + nameOrBytes : names[0].replace('\\', '/')); if (names != null) image = jmb.getImage(vwr, nameOrError, echoName); + } else { + image = nameOrBytes; } if (bytes != null) image = jmb.getImage(vwr, bytes, echoName); @@ -949,7 +950,7 @@ return new String[] { null }; boolean doSetPathForAllFiles = (pathForAllFiles.length() > 0); if (name.startsWith("?") || name.startsWith("http://?")) { - if ((name = vwr.dialogAsk("Load", name)) == null) + if ((name = vwr.dialogAsk("Load", name, null)) == null) return new String[] { isFullLoad ? "#CANCELED#" : null }; doSetPathForAllFiles = false; } Modified: trunk/Jmol/src/org/jmol/viewer/Jmol.properties =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/viewer/Jmol.properties 2015-02-22 05:47:23 UTC (rev 20309) @@ -13,10 +13,23 @@ # important for the JavaScript version of Jmol. TODO: remove HTML5 dependency on synchronous file loading (check SCRIPT command for problems) -TODO: add 2D graphics panel for Ramachandran and NBO-style 2D graphics -- send to browser as data uri? +TODO: implement SHOW IMAGE in JavaScript/Browser -Jmol.___JmolVersion="14.3.12_2015.02.19" +Jmol.___JmolVersion="14.3.12_2015.02.21" +new feature: Windows BMP image reading + +new feature: (application only) show IMAGE + -- pops up a frame with the current image + +new feature: (application only) show IMAGE "filename" + -- pops up a frame with the image loaded from a file + +code: javajs.img.bMPDecoder +code: org.openscience.jmol.app.jmolpanel.ImageDialog + +JmolVersion="14.3.12_2015.02.19" + bug fix: "write image 500 500 png ?" broken JmolVersion="14.3.12_2015.02.18b" Modified: trunk/Jmol/src/org/jmol/viewer/OutputManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/OutputManager.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/viewer/OutputManager.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -135,12 +135,20 @@ boolean asBytes = (out == null && fileName == null); boolean closeChannel = (out == null && fileName != null); boolean releaseImage = (objImage == null); - Object image = (type.equals("BINARY") || type.equals("ZIPDATA") ? "" : rgbbuf != null ? rgbbuf - : objImage != null ? objImage : vwr.getScreenImageBuffer(null, true)); + Object image = (type.equals("BINARY") || type.equals("ZIPDATA") ? "" + : rgbbuf != null ? rgbbuf : objImage != null ? objImage : vwr + .getScreenImageBuffer(null, true)); boolean isOK = false; try { if (image == null) return errMsg = vwr.getErrorMessage(); + if (fileName != null && fileName.startsWith("\1")) { + isOK = true; + Map<String, Object> info = new Hashtable<String, Object>(); + info.put("_IMAGE_", image); + vwr.fm.loadImage(info, fileName); + return errMsg = "OK - viewing " + fileName.substring(1); + } if (out == null) out = openOutputChannel(privateKey, fileName, false, false); if (out == null) @@ -168,7 +176,8 @@ OC outTemp = getOutputChannel(null, null); getWrappedState(fileName, scripts, image, outTemp); stateData = outTemp.toByteArray(); - } else if (rgbbuf == null && !asBytes && !params.containsKey("captureMode")) { + } else if (rgbbuf == null && !asBytes + && !params.containsKey("captureMode")) { stateData = ((String) getWrappedState(null, scripts, image, null)) .getBytes(); } @@ -178,10 +187,10 @@ } } if (type.equals("PNGT") || type.equals("GIFT")) - params.put("transparentColor", - Integer.valueOf(vwr.getBackgroundArgb())); + params + .put("transparentColor", Integer.valueOf(vwr.getBackgroundArgb())); if (type.length() == 4) // PNGT PNGJ GIFT - type = type.substring(0, 3); + type = type.substring(0, 3); if (comment != null) params.put("comment", comment.length() == 0 ? Viewer.getJmolVersion() : comment); @@ -190,7 +199,8 @@ if (closeChannel) out.closeChannel(); if (isOK) { - if (params.containsKey("captureMsg") && !params.containsKey("captureSilent")) + if (params.containsKey("captureMsg") + && !params.containsKey("captureSilent")) vwr.prompt((String) params.get("captureMsg"), "OK", null, true); if (asBytes) bytes = out.toByteArray(); @@ -203,8 +213,9 @@ } finally { if (releaseImage) vwr.releaseScreenImage(); - params.put("byteCount", Integer.valueOf(bytes != null ? bytes.length - : isOK ? out.getByteCount() : -1)); + if (bytes != null || out != null) + params.put("byteCount", Integer.valueOf(bytes != null ? bytes.length + : isOK ? out.getByteCount() : -1)); if (objImage != null) { // _ObjExport is saving the texture file -- just return file name, regardless of whether there is an error return fileName; @@ -365,7 +376,7 @@ if (!vwr.haveAccess(ACCESS.ALL)) return null; if (fileName != null) { - fileName = getOutputFileNameFromDialog(fileName, Integer.MIN_VALUE); + fileName = getOutputFileNameFromDialog(fileName, Integer.MIN_VALUE, null); if (fileName == null) return null; } @@ -411,7 +422,7 @@ int n = 0; int quality = getInt(params, "quality", -1); fileName = setFullPath(params, getOutputFileNameFromDialog(fileName, - quality)); + quality, null)); if (fileName == null) return null; String[] rootExt = new String[2]; @@ -474,7 +485,7 @@ String fileName = (String) params.get("fileName"); if (fileName != null) { fileName = setFullPath(params, getOutputFileNameFromDialog(fileName, - Integer.MIN_VALUE)); + Integer.MIN_VALUE, null)); if (fileName == null) return null; } @@ -544,13 +555,13 @@ * @param type * one of: PDB PQR FILE PLOT * @param modelIndex - * @param parameters + * @param plotParameters * @return "OK..." or "" or null * */ String writeFileData(String fileName, String type, int modelIndex, - Object[] parameters) { + Object[] plotParameters) { String[] fullPath = new String[1]; OC out = getOutputChannel(fileName, fullPath); if (out == null) @@ -574,7 +585,7 @@ type.startsWith("PDB") ? vwr.getPdbAtomData(null, out, false, false) : type.startsWith("PLOT") ? - vwr.getPdbData(modelIndex, type.substring(5), null, parameters, out, true) + vwr.getPdbData(modelIndex, type.substring(5), null, plotParameters, out, true) : getCurrentFile ? out.append(vwr.getCurrentFileAsString("write")).toString() : (String) vwr.fm.getFileAsBytes(pathName, out)); @@ -596,7 +607,7 @@ return msg.startsWith("OK"); } - private String getOutputFileNameFromDialog(String fileName, int quality) { + private String getOutputFileNameFromDialog(String fileName, int quality, Map<String, Object> params) { if (fileName == null || vwr.isKiosk) return null; boolean useDialog = fileName.startsWith("?"); @@ -606,7 +617,7 @@ fileName = FileManager.getLocalPathForWritingFile(vwr, fileName); if (useDialog) fileName = vwr.dialogAsk(quality == Integer.MIN_VALUE ? "Save" - : "Save Image", fileName); + : "Save Image", fileName, params); return fileName; } @@ -650,9 +661,11 @@ doCheck = false; // will be checked later mustRender = false; } - if (doCheck) - fileName = getOutputFileNameFromDialog(fileName, quality); - fileName = setFullPath(params, fileName); + if (!fileName.startsWith("\1")) { + if (doCheck) + fileName = getOutputFileNameFromDialog(fileName, quality, params); + fileName = setFullPath(params, fileName); + } if (fileName == null) return null; params.put("fileName", fileName); Modified: trunk/Jmol/src/org/jmol/viewer/StatusManager.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/StatusManager.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/viewer/StatusManager.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -353,6 +353,13 @@ new Object[] {sJmol, strInfo, Integer.valueOf(-1), id, Float.valueOf(pt.x), Float.valueOf(pt.y), Float.valueOf(pt.z) }); } + synchronized void showImage(String title, Object image) { + String sJmol = jmolScriptCallback(CBK.IMAGE); + if (notifyEnabled(CBK.IMAGE)) + cbl.notifyCallback(CBK.IMAGE, + new Object[] {sJmol, title, image }); + } + synchronized void setFileLoadStatus(String fullPathName, String fileName, String modelName, String errorMsg, int ptLoad, boolean doCallback, @@ -701,22 +708,28 @@ private int qualityPNG = -1; private String imageType; - String dialogAsk(String type, String fileName) { + String dialogAsk(String type, String fileName, Map<String, Object> params) { boolean isImage = type.equals("Save Image"); - JmolDialogInterface sd = (JmolDialogInterface) Interface - .getOption("dialog.Dialog", vwr, "status"); + JmolDialogInterface sd = (JmolDialogInterface) Interface.getOption( + "dialog.Dialog", vwr, "status"); if (sd == null) return null; sd.setupUI(false); - if (isImage) + if (isImage) sd.setImageInfo(qualityJPG, qualityPNG, imageType); - String outputFileName = sd.getFileNameFromDialog(vwr, type, fileName); // may have #NOCARTOONS#; and/or "#APPEND#; prepended + String outputFileName = sd.getFileNameFromDialog(vwr, type, fileName); // may have #NOCARTOONS#; and/or "#APPEND#; prepended // may have #NOCARTOONS#; and/or "#APPEND#; prepended - + if (isImage && outputFileName != null) { qualityJPG = sd.getQuality("JPG"); qualityPNG = sd.getQuality("PNG"); String sType = sd.getType(); + if (params != null) { + params.put("qualityJPG", Integer.valueOf(qualityJPG)); + params.put("qualityPNG", Integer.valueOf(qualityPNG)); + if (sType != null) + params.put("dialogImageType", sType); + } if (sType != null) imageType = sType; } Modified: trunk/Jmol/src/org/jmol/viewer/Viewer.java =================================================================== --- trunk/Jmol/src/org/jmol/viewer/Viewer.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/jmol/viewer/Viewer.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -4764,7 +4764,7 @@ * StatusManager.syncSend Viewer.setSyncTarget Viewer.syncScript */ - String dialogAsk(String type, String fileName) { + public String dialogAsk(String type, String fileName, Map<String, Object> params) { /** * @j2sNative * @@ -4774,7 +4774,7 @@ { // may have #NOCARTOONS#; and/or "#APPEND#; prepended return (isKiosk || !haveAccess(ACCESS.ALL) ? null : sm.dialogAsk(type, - fileName)); + fileName, params)); } } @@ -7985,6 +7985,8 @@ scriptEcho(nameOrError); if (echoName == null) { setBackgroundImage((image == null ? null : nameOrError), image); + } else if (echoName.startsWith("\1")){ + sm.showImage(echoName.substring(1), image); } else { shm.loadShape(JC.SHAPE_ECHO); setShapeProperty(JC.SHAPE_ECHO, "text", nameOrError); @@ -7995,7 +7997,6 @@ sc.mustResumeEval = true; eval.resumeEval(sc); } - } public String cd(String dir) { Modified: trunk/Jmol/src/org/molecularplayground/MPJmolApp.java =================================================================== --- trunk/Jmol/src/org/molecularplayground/MPJmolApp.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/molecularplayground/MPJmolApp.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -250,6 +250,7 @@ } // / JmolCallbackListener interface /// + @SuppressWarnings("incomplete-switch") @Override public boolean notifyEnabled(CBK type) { switch (type) { @@ -257,23 +258,6 @@ case ECHO: case MESSAGE: return true; - case ANIMFRAME: - case APPLETREADY: - case ATOMMOVED: - case CLICK: - case ERROR: - case EVAL: - case HOVER: - case LOADSTRUCT: - case MEASURE: - case MINIMIZATION: - case SERVICE: - case PICK: - case RESIZE: - case SYNC: - case STRUCTUREMODIFIED: - case DRAGDROP: - return false; } return false; } Modified: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/GuiMap.java =================================================================== --- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/GuiMap.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/GuiMap.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -67,6 +67,7 @@ private void setupLabels() { labels = new Hashtable<String, String>(); labels.put("macros", GT._("&Macros")); + labels.put("idfileMenu", GT._("&File")); labels.put("file", GT._("&File")); labels.put("newwin", GT._("&New")); labels.put("open", GT._("&Open")); Added: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/ImageDialog.java =================================================================== --- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/ImageDialog.java (rev 0) +++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/ImageDialog.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -0,0 +1,211 @@ +/* $RCSfile$ + * $Author: hansonr $ + * $Date: 2014-03-20 17:22:16 -0500 (Thu, 20 Mar 2014) $ + * $Revision: 19476 $ + * + * Copyright (C) 2002-2005 The Jmol Development Team + * + * Contact: jmol-develop...@lists.sf.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ +package org.openscience.jmol.app.jmolpanel; + + +import javajs.util.PT; + +import javax.swing.ImageIcon; +import javax.swing.JDialog; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.awt.Image; +import java.util.Hashtable; +import java.util.Map; + +import org.jmol.viewer.Viewer; + +class ImageDialog extends JDialog implements WindowListener, ActionListener { + + + private JMenuBar menubar; + + protected Image image; + + protected Viewer vwr; + protected Canvas canvas; + private String title; + private Map<String, ImageDialog> imageMap; + + ImageDialog(JmolPanel jmol, Viewer vwr, String title, Map<String, ImageDialog> imageMap) { + super(jmol.frame, title, false); + this.vwr = vwr; + addWindowListener(this); + this.title = title; + this.imageMap = imageMap; + imageMap.put(title, this); + JPanel wrapper = new JPanel(new BorderLayout()); + canvas = new ImageCanvas(); + wrapper.add(canvas, BorderLayout.CENTER); + JPanel container = new JPanel(); + container.setLayout(new BorderLayout()); + menubar = new JMenuBar(); + // see app.jmolpanel.jmol.Properties.Jmol-reseources.properties + menubar.add(createMenu(jmol.guimap, "idfileMenu")); + setJMenuBar(menubar); + container.add(wrapper, BorderLayout.CENTER); + getContentPane().add(container); + pack(); + setLocation(100, 100); + setVisible(true); + } + + private JMenu createMenu(GuiMap guimap, String key) { + + // Get list of items from resource file: + String[] itemKeys = PT.getTokens(JmolResourceHandler.getStringX(key)); + // Get label associated with this menu: + JMenu menu = guimap.newJMenu(key); + ImageIcon f = JmolResourceHandler.getIconX(key + "Image"); + if (f != null) { + menu.setHorizontalTextPosition(SwingConstants.RIGHT); + menu.setIcon(f); + } + + // Loop over the items in this menu: + for (int i = 0; i < itemKeys.length; i++) { + String item = itemKeys[i]; + if (item.equals("-")) { + menu.addSeparator(); + } else if (item.endsWith("Menu")) { + menu.add(createMenu(guimap, item)); + } else { + JMenuItem mi = createMenuItem(guimap, item); + menu.add(mi); + } + } + menu.setVisible(true); + return menu; + } + + private JMenuItem createMenuItem(GuiMap guimap, String cmd) { + + JMenuItem mi = guimap.newJMenuItem(cmd); + ImageIcon f = JmolResourceHandler.getIconX(cmd + "Image"); + if (f != null) { + mi.setHorizontalTextPosition(SwingConstants.RIGHT); + mi.setIcon(f); + } + mi.setActionCommand(cmd); + mi.addActionListener(this); + mi.setVisible(true); + return mi; + } + + @Override + public void actionPerformed(ActionEvent e) { + String cmd = e.getActionCommand(); + if (cmd.equals("close")) { + closeMe(); + } else if (cmd.equals("saveas")) { + saveAs(); + } + } + + private void saveAs() { + (new Thread(new Runnable() { + @Override + public void run() { + Map<String, Object>params = new Hashtable<String, Object>(); + String fname = vwr.dialogAsk("Save Image", "jmol.png", params); + if (fname == null) + return; + String type = "PNG"; + int pt = fname.lastIndexOf("."); + if (pt > 0) + type = fname.substring(pt + 1).toUpperCase(); + params.put("fileName", fname); + params.put("type", type); + params.put("image", image); + vwr.showString(vwr.processWriteOrCapture(params), false); + } + }) { + }).start(); + } + + private void closeMe() { + imageMap.remove(title); + dispose(); + } + + public void setImage(Image image) { + if (image != null) { + this.image = image; + int w = image.getWidth(null); + int h = image.getHeight(null); + setTitle(title.substring(title.lastIndexOf("/") + 1) + " [" + w + " x " + h + "]"); + Dimension d = new Dimension(w, h); + canvas.setSize(d); + //canvas.setBackground(new Color(55,0,0)); + //setPreferredSize(d); + pack(); + } + repaint(); + } + + + class ImageCanvas extends Canvas { + @Override + public void paint(Graphics g) { + g.drawImage(image, 0, 0, null); + } + } + + @Override + public void windowClosed(WindowEvent e) { + } + + @Override + public void windowOpened(WindowEvent e) { + } + @Override + public void windowClosing(WindowEvent e) { + closeMe(); + } + @Override + public void windowIconified(WindowEvent e) { + } + @Override + public void windowDeiconified(WindowEvent e) { + } + @Override + public void windowActivated(WindowEvent e) { + } + @Override + public void windowDeactivated(WindowEvent e) { + } + +} Property changes on: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/ImageDialog.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Modified: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/JmolPanel.java =================================================================== --- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/JmolPanel.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/JmolPanel.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -80,8 +80,9 @@ import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.StringTokenizer; +import javajs.util.PT; + import javax.swing.AbstractAction; import javax.swing.AbstractButton; import javax.swing.Action; @@ -140,7 +141,6 @@ private Map<String, Action> commands; private Map<String, JMenuItem> menuItems; - private JMenuBar menubar; private JToolBar toolbar; // --- action implementations ----------------------------------- @@ -309,7 +309,7 @@ menuItems = new Hashtable<String, JMenuItem>(); say(GT._("Building Menubar...")); executeScriptAction = new ExecuteScriptAction(); - menubar = createMenubar(); + JMenuBar menubar = createMenubar(); add("North", menubar); panel.setLayout(new BorderLayout()); toolbar = createToolbar(); @@ -672,7 +672,7 @@ * @return Menu item created * @see #getMenuItem */ - protected JMenuItem createMenuItem(String cmd) { + private JMenuItem createMenuItem(String cmd) { JMenuItem mi; if (cmd.endsWith("Check")) { @@ -734,7 +734,7 @@ private JToolBar createToolbar() { toolbar = new JToolBar(); - String[] tool1Keys = tokenize(JmolResourceHandler.getStringX("toolbar")); + String[] tool1Keys = PT.getTokens(JmolResourceHandler.getStringX("toolbar")); for (int i = 0; i < tool1Keys.length; i++) { if (tool1Keys[i].equals("-")) { toolbar.addSeparator(); @@ -826,27 +826,11 @@ } /** - * Take the given string and chop it up into a series - * of strings on whitespace boundries. This is useful - * for trying to get an array of strings out of the - * resource file. - * @param input String to chop - * @return Strings chopped on whitespace boundaries - */ - protected String[] tokenize(String input) { - List<String> v = new ArrayList<String>(); - StringTokenizer t = new StringTokenizer(input); - while (t.hasMoreTokens()) - v.add(t.nextToken()); - return v.toArray(new String[v.size()]); - } - - /** * Create the menubar for the app. By default this pulls the * definition of the menu from the associated resource file. * @return Menubar */ - protected JMenuBar createMenubar() { + private JMenuBar createMenubar() { JMenuBar mb = new JMenuBar(); addNormalMenuBar(mb); // The Macros Menu @@ -861,7 +845,7 @@ return mb; } - protected void addMacrosMenuBar(JMenuBar menuBar) { + private void addMacrosMenuBar(JMenuBar menuBar) { // ok, here needs to be added the funny stuff JMenu macroMenu = guimap.newJMenu("macros"); File macroDir = new File(System.getProperty("user.home") @@ -908,8 +892,8 @@ menuBar.add(macroMenu); } - protected void addNormalMenuBar(JMenuBar menuBar) { - String[] menuKeys = tokenize(JmolResourceHandler.getStringX("menubar")); + private void addNormalMenuBar(JMenuBar menuBar) { + String[] menuKeys = PT.getTokens(JmolResourceHandler.getStringX("menubar")); for (int i = 0; i < menuKeys.length; i++) { if (menuKeys[i].equals("-")) { menuBar.add(Box.createHorizontalGlue()); @@ -921,7 +905,7 @@ } } - protected void addHelpMenuBar(JMenuBar menuBar) { + private void addHelpMenuBar(JMenuBar menuBar) { JMenu m = createMenu("help"); if (m != null) { menuBar.add(m); @@ -934,10 +918,10 @@ * @param key * @return Menu created */ - protected JMenu createMenu(String key) { + JMenu createMenu(String key) { // Get list of items from resource file: - String[] itemKeys = tokenize(JmolResourceHandler.getStringX(key)); + String[] itemKeys = PT.getTokens(JmolResourceHandler.getStringX(key)); // Get label associated with this menu: JMenu menu = guimap.newJMenu(key); ImageIcon f = JmolResourceHandler.getIconX(key + "Image"); Modified: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/NBODialog.java =================================================================== --- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/NBODialog.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/NBODialog.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -32,7 +32,6 @@ import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; -import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; Modified: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/Properties/Jmol-resources.properties =================================================================== --- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/Properties/Jmol-resources.properties 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/Properties/Jmol-resources.properties 2015-02-22 05:47:23 UTC (rev 20309) @@ -301,4 +301,9 @@ <li><a href="http://jas.freehep.org/">Java Analysis Studio</a> (jas.freehep.org)</li>\ <li><a href="http://www.icon-king.com/projects/nuvola">Nuvola icon library</a> (www.icon-king.com/projects/nuvola, David Vignoni)</li>\ </ul> +# +# ImageDialog +# +imageDialog.menubar=idfileMenu +idfileMenu=saveas close Modified: trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/StatusListener.java =================================================================== --- trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/StatusListener.java 2015-02-20 00:48:33 UTC (rev 20308) +++ trunk/Jmol/src/org/openscience/jmol/app/jmolpanel/StatusListener.java 2015-02-22 05:47:23 UTC (rev 20309) @@ -39,10 +39,12 @@ import org.openscience.jmol.app.webexport.WebExport; import java.awt.Component; +import java.awt.Image; import java.io.FileInputStream; import java.io.FileOutputStream; import java.lang.reflect.Method; import java.net.URI; +import java.util.Hashtable; import java.util.Map; import java.util.Properties; @@ -92,6 +94,7 @@ switch (type) { case ANIMFRAME: case ECHO: + case IMAGE: case LOADSTRUCT: case STRUCTUREMODIFIED: case MEASURE: @@ -123,6 +126,9 @@ .toString()); Map<String, Object> info; switch (type) { + case IMAGE: + notifyImageCreated(strInfo, (Image) data[2]); + return; case LOADSTRUCT: notifyFileLoaded(strInfo, (String) data[2], (String) data[3], (String) data[4], (Boolean) data[8]); @@ -222,6 +228,16 @@ appConsole.notifyCallback(type, data); } + private Map<String, ImageDialog> imageMap; + private void notifyImageCreated(String title, Image image) { + if (imageMap == null) + imageMap = new Hashtable<String, ImageDialog>(); + ImageDialog d = imageMap.get(title); + if (d == null) + d = new ImageDialog(jmol, vwr, title, imageMap); + d.setImage(image); + } + /** * @param atomIndex * @param modelIndex This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server from Actuate! Instantly Supercharge Your Business Reports and Dashboards with Interactivity, Sharing, Native Excel Exports, App Integration & more Get technology previously reserved for billion-dollar corporations, FREE http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk _______________________________________________ Jmol-commits mailing list Jmol-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jmol-commits