+ }
+
+ public static groovy.ui.Console getGroovyConsole()
+ {
+ return groovyConsole;
+ }
+
+ /**
+ * handles the payload of a drag and drop event.
+ *
+ * TODO refactor to desktop utilities class
+ *
+ * @param files
+ * - Data source strings extracted from the drop event
+ * @param protocols
+ * - protocol for each data source extracted from the drop event
+ * @param evt
+ * - the drop event
+ * @param t
+ * - the payload from the drop event
+ * @throws Exception
+ */
+ public static void transferFromDropTarget(List<Object> files,
+ List<DataSourceType> protocols, DropTargetDropEvent evt,
+ Transferable t) throws Exception
+ {
+
+ DataFlavor uriListFlavor = new DataFlavor(
+ "text/uri-list;class=java.lang.String"), urlFlavour = null;
+ try
+ {
+ urlFlavour = new DataFlavor(
+ "application/x-java-url; class=java.net.URL");
+ } catch (ClassNotFoundException cfe)
+ {
+ jalview.bin.Console.debug("Couldn't instantiate the URL dataflavor.",
+ cfe);
+ }
+
+ if (urlFlavour != null && t.isDataFlavorSupported(urlFlavour))
+ {
+
+ try
+ {
+ java.net.URL url = (URL) t.getTransferData(urlFlavour);
+ // nb: java 8 osx bug https://bugs.openjdk.java.net/browse/JDK-8156099
+ // means url may be null.
+ if (url != null)
+ {
+ protocols.add(DataSourceType.URL);
+ files.add(url.toString());
+ jalview.bin.Console.debug("Drop handled as URL dataflavor "
+ + files.get(files.size() - 1));
+ return;
+ }
+ else
+ {
+ if (Platform.isAMacAndNotJS())
+ {
+ System.err.println(
+ "Please ignore plist error - occurs due to problem with java 8 on OSX");
+ }
+ }
+ } catch (Throwable ex)
+ {
+ jalview.bin.Console.debug("URL drop handler failed.", ex);
+ }
+ }
+ if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+ {
+ // Works on Windows and MacOSX
+ jalview.bin.Console.debug("Drop handled as javaFileListFlavor");
+ for (Object file : (List) t
+ .getTransferData(DataFlavor.javaFileListFlavor))
+ {
+ files.add(file);
+ protocols.add(DataSourceType.FILE);
+ }
+ }
+ else
+ {
+ // Unix like behaviour
+ boolean added = false;
+ String data = null;
+ if (t.isDataFlavorSupported(uriListFlavor))
+ {
+ jalview.bin.Console.debug("Drop handled as uriListFlavor");
+ // This is used by Unix drag system
+ data = (String) t.getTransferData(uriListFlavor);
+ }
+ if (data == null)
+ {
+ // fallback to text: workaround - on OSX where there's a JVM bug
+ jalview.bin.Console
+ .debug("standard URIListFlavor failed. Trying text");
+ // try text fallback
+ DataFlavor textDf = new DataFlavor(
+ "text/plain;class=java.lang.String");
+ if (t.isDataFlavorSupported(textDf))
+ {
+ data = (String) t.getTransferData(textDf);
+ }
+
+ jalview.bin.Console.debug("Plain text drop content returned "
+ + (data == null ? "Null - failed" : data));
+
+ }
+ if (data != null)
+ {
+ while (protocols.size() < files.size())
+ {
+ jalview.bin.Console.debug("Adding missing FILE protocol for "
+ + files.get(protocols.size()));
+ protocols.add(DataSourceType.FILE);
+ }
+ for (java.util.StringTokenizer st = new java.util.StringTokenizer(
+ data, "\r\n"); st.hasMoreTokens();)
+ {
+ added = true;
+ String s = st.nextToken();
+ if (s.startsWith("#"))
+ {
+ // the line is a comment (as per the RFC 2483)
+ continue;
+ }
+ java.net.URI uri = new java.net.URI(s);
+ if (uri.getScheme().toLowerCase(Locale.ROOT).startsWith("http"))
+ {
+ protocols.add(DataSourceType.URL);
+ files.add(uri.toString());
+ }
+ else
+ {
+ // otherwise preserve old behaviour: catch all for file objects
+ java.io.File file = new java.io.File(uri);
+ protocols.add(DataSourceType.FILE);
+ files.add(file.toString());
+ }
+ }
+ }
+
+ if (jalview.bin.Console.isDebugEnabled())
+ {
+ if (data == null || !added)
+ {
+
+ if (t.getTransferDataFlavors() != null
+ && t.getTransferDataFlavors().length > 0)
+ {
+ jalview.bin.Console.debug(
+ "Couldn't resolve drop data. Here are the supported flavors:");
+ for (DataFlavor fl : t.getTransferDataFlavors())
+ {
+ jalview.bin.Console.debug(
+ "Supported transfer dataflavor: " + fl.toString());
+ Object df = t.getTransferData(fl);
+ if (df != null)
+ {
+ jalview.bin.Console.debug("Retrieves: " + df);
+ }
+ else
+ {
+ jalview.bin.Console.debug("Retrieved nothing");
+ }
+ }
+ }
+ else
+ {
+ jalview.bin.Console
+ .debug("Couldn't resolve dataflavor for drop: "
+ + t.toString());
+ }
+ }
+ }
+ }
+ if (Platform.isWindowsAndNotJS())
+ {
+ jalview.bin.Console
+ .debug("Scanning dropped content for Windows Link Files");
+
+ // resolve any .lnk files in the file drop
+ for (int f = 0; f < files.size(); f++)
+ {
+ String source = files.get(f).toString().toLowerCase(Locale.ROOT);
+ if (protocols.get(f).equals(DataSourceType.FILE)
+ && (source.endsWith(".lnk") || source.endsWith(".url")
+ || source.endsWith(".site")))
+ {
+ try
+ {
+ Object obj = files.get(f);
+ File lf = (obj instanceof File ? (File) obj
+ : new File((String) obj));
+ // process link file to get a URL
+ jalview.bin.Console.debug("Found potential link file: " + lf);
+ WindowsShortcut wscfile = new WindowsShortcut(lf);
+ String fullname = wscfile.getRealFilename();
+ protocols.set(f, FormatAdapter.checkProtocol(fullname));
+ files.set(f, fullname);
+ jalview.bin.Console.debug("Parsed real filename " + fullname
+ + " to extract protocol: " + protocols.get(f));
+ } catch (Exception ex)
+ {
+ jalview.bin.Console.error(
+ "Couldn't parse " + files.get(f) + " as a link file.",
+ ex);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the Preferences property for experimental features to True or False
+ * depending on the state of the controlling menu item
+ */
+ @Override
+ protected void showExperimental_actionPerformed(boolean selected)
+ {
+ Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));
+ }
+
+ /**
+ * Answers a (possibly empty) list of any structure viewer frames (currently
+ * for either Jmol or Chimera) which are currently open. This may optionally
+ * be restricted to viewers of a specified class, or viewers linked to a
+ * specified alignment panel.
+ *
+ * @param apanel
+ * if not null, only return viewers linked to this panel
+ * @param structureViewerClass
+ * if not null, only return viewers of this class
+ * @return
+ */
+ public List<StructureViewerBase> getStructureViewers(
+ AlignmentPanel apanel,
+ Class<? extends StructureViewerBase> structureViewerClass)
+ {
+ List<StructureViewerBase> result = new ArrayList<>();
+ JInternalFrame[] frames = Desktop.instance.getAllFrames();