upgraded Platform.java
[jalview.git] / src / jalview / util / Platform.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.util;
22
23 import java.awt.Toolkit;
24 import java.awt.event.MouseEvent;
25 import java.io.File;
26 import java.util.Properties;
27
28 import javax.swing.SwingUtilities;
29
30 /**
31  * System platform information used by Applet and Application
32  * 
33  * @author Jim Procter
34  */
35 public class Platform
36 {
37
38   private static boolean isJS = /** @j2sNative true || */false;
39
40   private static Boolean isNoJSMac = null, isNoJSWin = null, 
41                   isMac = null, isWin = null;
42   
43   private static Boolean isHeadless = null;
44
45   /**
46    * added to group mouse events into Windows and nonWindows (mac, unix, linux)
47    * @return
48    */
49   public static boolean isMac()
50   {
51           return (isMac == null ? (isMac = (System.getProperty("os.name").indexOf("Mac") >= 0)) : isMac);
52   }
53
54   /**
55    * added to group mouse events into Windows and nonWindows (mac, unix, linux)
56    * @return
57    */
58   public static boolean isWin() 
59   {
60           return (isWin == null ? (isWin = (System.getProperty("os.name").indexOf("Win") >= 0)) : isWin);
61   }
62
63   /**
64    * 
65    * @return true if HTML5 JavaScript
66    */
67   public static boolean isJS()
68   {
69         return isJS;
70   }
71
72   /**
73    * sorry folks - Macs really are different
74    * 
75    * BH: disabled for SwingJS -- will need to check key-press issues
76    * 
77    * @return true if we do things in a special way.
78    */
79   public static boolean isAMacAndNotJS()
80   {
81         return (isNoJSMac == null ? (isNoJSMac = !isJS && isMac()) : isNoJSMac);
82   }
83
84 /**
85    * Check if we are on a Microsoft plaform...
86    * 
87    * @return true if we have to cope with another platform variation
88    */
89   public static boolean isWindowsAndNotJS()
90   {
91         return (isNoJSWin == null ? (isNoJSWin = !isJS && isWin()) : isNoJSWin);
92    }
93
94   /**
95    * 
96    * @return true if we are running in non-interactive no UI mode
97    */
98   public static boolean isHeadless()
99   {
100     if (isHeadless == null)
101     {
102       isHeadless = "true".equals(System.getProperty("java.awt.headless"));
103     }
104     return isHeadless;
105   }
106
107   /**
108    * 
109    * @return nominal maximum command line length for this platform
110    */
111   public static int getMaxCommandLineLength()
112   {
113     // TODO: determine nominal limits for most platforms.
114     return 2046; // this is the max length for a windows NT system.
115   }
116
117   /**
118    * escape a string according to the local platform's escape character
119    * 
120    * @param file
121    * @return escaped file
122    */
123   public static String escapeString(String file)
124   {
125     StringBuffer f = new StringBuffer();
126     int p = 0, lastp = 0;
127     while ((p = file.indexOf('\\', lastp)) > -1)
128     {
129       f.append(file.subSequence(lastp, p));
130       f.append("\\\\");
131       lastp = p + 1;
132     }
133     f.append(file.substring(lastp));
134     return f.toString();
135   }
136
137   /**
138    * Answers true if the mouse event has Meta-down (Command key on Mac) or
139    * Ctrl-down (on other o/s). Note this answers _false_ if the Ctrl key is
140    * pressed instead of the Meta/Cmd key on Mac. To test for Ctrl-pressed on Mac,
141    * you can use e.isPopupTrigger().
142    * 
143    * @param e
144    * @return
145    */
146   public static boolean isControlDown(MouseEvent e)
147   {
148     return isControlDown(e, isMac());
149   }
150
151   /**
152    * Overloaded version of method (to allow unit testing)
153    * 
154    * @param e
155    * @param aMac
156    * @return
157    */
158   protected static boolean isControlDown(MouseEvent e, boolean aMac)
159   {
160     if (!aMac) {
161         return e.isControlDown();       
162     }
163       // answer false for right mouse button
164       // shortcut key will be META for a Mac 
165     return !e.isPopupTrigger() 
166                   && (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e.getModifiers()) != 0;
167       // could we use e.isMetaDown() here?
168   }
169
170   /**
171    * Windows (not Mac, Linux, or Unix) and right button
172    * to test for the right-mouse pressed event in Windows
173    * that would have opened a menu or a Mac. 
174    * 
175    * @param e
176    * @return
177    */
178   public static boolean isWinRightButton(MouseEvent e) 
179   {
180           // was !isAMac(), but that is true also for Linux and Unix and JS, 
181
182           return isWin() && SwingUtilities.isRightMouseButton(e);
183   }
184   
185   
186   /**
187    * Windows (not Mac, Linux, or Unix) and middle button -- for mouse wheeling 
188    * without pressing the button.
189    * 
190    * @param e
191    * @return
192    */
193   public static boolean isWinMiddleButton(MouseEvent e) 
194   {
195         // was !isAMac(), but that is true also for Linux and Unix and JS
196           return isWin() && SwingUtilities.isMiddleMouseButton(e);
197   }
198
199   public static boolean allowMnemonics() 
200   {
201         return !isMac();
202   }
203   
204   public final static int TIME_RESET = 0;
205   public final static int TIME_MARK  = 1;
206   public static final int TIME_SET   = 2;
207   public static final int TIME_GET   = 3;
208   
209   public static long time, mark, set, duration;
210   
211   public static void timeCheck(String msg, int mode) {
212           long t = System.currentTimeMillis();
213           switch (mode) {
214           case TIME_RESET:
215                   time = mark = t;
216                   if (msg != null)
217                   System.err.println("Platform: timer reset\t\t\t" + msg);
218                   break;
219           case TIME_MARK:
220                   if (set > 0) {
221                           duration += (t - set);
222                   } else {
223                   if (time == 0)
224                           time = mark = t;
225                           if (msg != null)
226                   System.err.println("Platform: timer mark\t" + ((t - time)/1000f) + "\t" + ((t - mark)/1000f) + "\t" + msg);
227                   mark = t;
228                   }
229                   break;
230           case TIME_SET:
231                   set = t;
232                   break;
233           case TIME_GET:
234                   if (msg != null)
235                           System.err.println("Platform: timer dur\t" + ((t - time)/1000f) + "\t" + ((duration)/1000f) + "\t" + msg);
236                   set = 0;
237                   break;
238           }
239   }
240
241   public static void cacheFileData(String path, byte[] data)  
242   {
243         if (!isJS())
244                 return;
245           /**
246            * @j2sNative 
247            *   
248            *   swingjs.JSUtil.cacheFileData$S$O(path, data);
249            * 
250            */
251   }
252
253   public static byte[] getFileBytes(File f) 
254   {
255         return /** @j2sNative   f && f._bytes || */null;
256   }
257
258   public static byte[] getFileAsBytes(String fileStr) 
259   {
260     // BH 2018 hack for no support for access-origin
261         return /** @j2sNative swingjs.JSUtil.getFileAsBytes$O(fileStr) || */ null;
262   }
263
264   public static String getFileAsString(String data) 
265   {
266         return /** @j2sNative swingjs.JSUtil.getFileAsString$S(data) || */ null;
267   }
268
269   public static boolean setFileBytes(File f, String urlstring) 
270   {
271         if (!isJS()) 
272                 return false;
273         @SuppressWarnings("unused")
274         byte[] bytes = getFileAsBytes(urlstring);
275                     /** @j2sNative 
276                      * f._bytes = bytes; 
277                      */
278         return true;
279   }
280
281    
282   public static void addJ2SBinaryType(String ext)
283   {
284   /**
285    * @j2sNative
286    * 
287    *            J2S._binaryTypes.push("." + ext + "?");
288    * 
289    */
290   }
291
292   public static String encodeURI(String value) 
293   {
294     /**
295      * @j2sNative
296      * return encodeURIComponent(value);
297      */
298         return value;
299   }
300
301   public static boolean openURL(String url) 
302   {
303         if (!isJS()) 
304                 return false;
305                 /**
306                  * @j2sNative
307                  * 
308                  * 
309                  *                      window.open(url);
310                  */
311         return true;
312   }
313
314         public static String getUniqueAppletID() {
315                 @SuppressWarnings("unused")
316                 ThreadGroup g = Thread.currentThread().getThreadGroup();
317                 /**
318                  * @j2sNative return g.html5Applet._uniqueId;
319                  *
320                  */
321                 return null;
322
323         }
324   /**
325    * Read the Info block for this applet. 
326    * 
327    * @param prefix "jalview_"
328    * @param p
329    * @return   unique id for this applet
330    */
331   public static void readInfoProperties(String prefix, Properties p) 
332   {
333           @SuppressWarnings("unused")
334         ThreadGroup g = Thread.currentThread().getThreadGroup(); 
335           String id = getUniqueAppletID();
336           String key = "", value = "";
337           /**
338            * @j2sNative
339                var info = g.html5Applet.__Info || {};
340                for (var key in info) {
341                   if (key.indexOf(prefix) == 0) {
342                      value = "" + info[key];
343         */
344          
345           p.put(id + "_" + key, value);
346           
347           /**
348            * @j2sNative
349
350                
351                   }
352                }
353            */
354   }
355
356
357 }