/* * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) * Copyright (C) $$Year-Rel$$ The Jalview Authors * * This file is part of Jalview. * * Jalview is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * Jalview 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Jalview. If not, see . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.util; import java.awt.Toolkit; import java.awt.event.MouseEvent; import java.io.File; import java.util.Properties; import javax.swing.SwingUtilities; /** * System platform information used by Applet and Application * * @author Jim Procter */ public class Platform { private static boolean isJS = /** @j2sNative true || */false; private static Boolean isNoJSMac = null, isNoJSWin = null, isMac = null, isWin = null; private static Boolean isHeadless = null; /** * added to group mouse events into Windows and nonWindows (mac, unix, linux) * @return */ public static boolean isMac() { return (isMac == null ? (isMac = (System.getProperty("os.name").indexOf("Mac") >= 0)) : isMac); } /** * added to group mouse events into Windows and nonWindows (mac, unix, linux) * @return */ public static boolean isWin() { return (isWin == null ? (isWin = (System.getProperty("os.name").indexOf("Win") >= 0)) : isWin); } /** * * @return true if HTML5 JavaScript */ public static boolean isJS() { return isJS; } /** * sorry folks - Macs really are different * * BH: disabled for SwingJS -- will need to check key-press issues * * @return true if we do things in a special way. */ public static boolean isAMacAndNotJS() { return (isNoJSMac == null ? (isNoJSMac = !isJS && isMac()) : isNoJSMac); } /** * Check if we are on a Microsoft plaform... * * @return true if we have to cope with another platform variation */ public static boolean isWindowsAndNotJS() { return (isNoJSWin == null ? (isNoJSWin = !isJS && isWin()) : isNoJSWin); } /** * * @return true if we are running in non-interactive no UI mode */ public static boolean isHeadless() { if (isHeadless == null) { isHeadless = "true".equals(System.getProperty("java.awt.headless")); } return isHeadless; } /** * * @return nominal maximum command line length for this platform */ public static int getMaxCommandLineLength() { // TODO: determine nominal limits for most platforms. return 2046; // this is the max length for a windows NT system. } /** * escape a string according to the local platform's escape character * * @param file * @return escaped file */ public static String escapeString(String file) { StringBuffer f = new StringBuffer(); int p = 0, lastp = 0; while ((p = file.indexOf('\\', lastp)) > -1) { f.append(file.subSequence(lastp, p)); f.append("\\\\"); lastp = p + 1; } f.append(file.substring(lastp)); return f.toString(); } /** * Answers true if the mouse event has Meta-down (Command key on Mac) or * Ctrl-down (on other o/s). Note this answers _false_ if the Ctrl key is * pressed instead of the Meta/Cmd key on Mac. To test for Ctrl-pressed on Mac, * you can use e.isPopupTrigger(). * * @param e * @return */ public static boolean isControlDown(MouseEvent e) { return isControlDown(e, isMac()); } /** * Overloaded version of method (to allow unit testing) * * @param e * @param aMac * @return */ protected static boolean isControlDown(MouseEvent e, boolean aMac) { if (!aMac) { return e.isControlDown(); } // answer false for right mouse button // shortcut key will be META for a Mac return !e.isPopupTrigger() && (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e.getModifiers()) != 0; // could we use e.isMetaDown() here? } // BH: I don't know about that previous method. Here is what SwingJS uses. // Notice the distinction in mouse events. (BUTTON3_MASK == META) // // private static boolean isPopupTrigger(int id, int mods, boolean isWin) { // boolean rt = ((mods & InputEvent.BUTTON3_MASK) != 0); // if (isWin) { // if (id != MouseEvent.MOUSE_RELEASED) // return false; //// //// // Oddly, Windows returns InputEvent.META_DOWN_MASK on release, though //// // BUTTON3_DOWN_MASK for pressed. So here we just accept both. //// //// actually, we can use XXX_MASK, not XXX_DOWN_MASK and avoid this issue, // because //// J2S adds the appropriate extended (0x3FC0) and simple (0x3F) modifiers. //// // return rt; // } else { // // mac, linux, unix // if (id != MouseEvent.MOUSE_PRESSED) // return false; // boolean lt = ((mods & InputEvent.BUTTON1_MASK) != 0); // boolean ctrl = ((mods & InputEvent.CTRL_MASK) != 0); // return rt || (ctrl && lt); // } // } // /** * Windows (not Mac, Linux, or Unix) and right button * to test for the right-mouse pressed event in Windows * that would have opened a menu or a Mac. * * @param e * @return */ public static boolean isWinRightButton(MouseEvent e) { // was !isAMac(), but that is true also for Linux and Unix and JS, return isWin() && SwingUtilities.isRightMouseButton(e); } /** * Windows (not Mac, Linux, or Unix) and middle button -- for mouse wheeling * without pressing the button. * * @param e * @return */ public static boolean isWinMiddleButton(MouseEvent e) { // was !isAMac(), but that is true also for Linux and Unix and JS return isWin() && SwingUtilities.isMiddleMouseButton(e); } public static boolean allowMnemonics() { return !isMac(); } public final static int TIME_RESET = 0; public final static int TIME_MARK = 1; public static final int TIME_SET = 2; public static final int TIME_GET = 3; public static long time, mark, set, duration; public static void timeCheck(String msg, int mode) { long t = System.currentTimeMillis(); switch (mode) { case TIME_RESET: time = mark = t; if (msg != null) { System.err.println("Platform: timer reset\t\t\t" + msg); } break; case TIME_MARK: if (set > 0) { duration += (t - set); } else { if (time == 0) { time = mark = t; } if (msg != null) { System.err.println("Platform: timer mark\t" + ((t - time)/1000f) + "\t" + ((t - mark)/1000f) + "\t" + msg); } mark = t; } break; case TIME_SET: set = t; break; case TIME_GET: if (msg != null) { System.err.println("Platform: timer dur\t" + ((t - time)/1000f) + "\t" + ((duration)/1000f) + "\t" + msg); } set = 0; break; } } public static void cacheFileData(String path, byte[] data) { if (!isJS()) { return; /** * @j2sNative * * swingjs.JSUtil.cacheFileData$S$O(path, data); * */ } } public static byte[] getFileBytes(File f) { return /** @j2sNative f && f._bytes || */null; } public static byte[] getFileAsBytes(String fileStr) { // BH 2018 hack for no support for access-origin return /** @j2sNative swingjs.JSUtil.getFileAsBytes$O(fileStr) || */ null; } public static String getFileAsString(String data) { return /** @j2sNative swingjs.JSUtil.getFileAsString$S(data) || */ null; } public static boolean setFileBytes(File f, String urlstring) { if (!isJS()) { return false; } @SuppressWarnings("unused") byte[] bytes = getFileAsBytes(urlstring); /** @j2sNative * f._bytes = bytes; */ return true; } public static void addJ2SBinaryType(String ext) { /** * @j2sNative * * J2S._binaryTypes.push("." + ext + "?"); * */ } public static String encodeURI(String value) { /** * @j2sNative * return encodeURIComponent(value); */ return value; } public static boolean openURL(String url) { if (!isJS()) { return false; } /** * @j2sNative * * * window.open(url); */ return true; } public static String getUniqueAppletID() { @SuppressWarnings("unused") ThreadGroup g = Thread.currentThread().getThreadGroup(); /** * @j2sNative return g.html5Applet._uniqueId; * */ return null; } /** * Read the Info block for this applet. * * @param prefix "jalview_" * @param p * @return unique id for this applet */ public static void readInfoProperties(String prefix, Properties p) { @SuppressWarnings("unused") ThreadGroup g = Thread.currentThread().getThreadGroup(); String id = getUniqueAppletID(); String key = "", value = ""; /** * @j2sNative var info = g.html5Applet.__Info || {}; for (var key in info) { if (key.indexOf(prefix) == 0) { value = "" + info[key]; */ p.put(id + "_" + key, value); /** * @j2sNative } } */ } }