/******************************************************************************* * Copyright (c) 2014 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.foundation.ui.util; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.IStatus; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTError; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.TextTransfer; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.browser.IWebBrowser; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.jboss.tools.foundation.core.IURLProvider; import org.jboss.tools.foundation.core.plugin.log.StatusFactory; import org.jboss.tools.foundation.ui.internal.FoundationUIPlugin; public class BrowserUtility { private static boolean browserLoadingErrorLoged; protected static Map<Integer, String> browserNames = new HashMap<Integer, String>(); static { browserNames.put(SWT.WEBKIT, "Webkit"); browserNames.put(SWT.MOZILLA, "Mozilla"); } /** * Opens a browser for the given url with the given id. If an error occurs * it will be reported to the given log provider with the given plugin id. * * @param url * the url to open a browser for. * @param browserId * the id for the new browser. * @param pluginId * the plugin id to log for. * @param log * the log provider to log against if an error occurred. */ public void checkedCreateInternalBrowser(String url, String browserId, String pluginId, ILog log) { try { openUrl(url, PlatformUI.getWorkbench().getBrowserSupport().createBrowser(IWorkbenchBrowserSupport.LOCATION_BAR | IWorkbenchBrowserSupport.NAVIGATION_BAR, browserId, null, null), pluginId, log); } catch (PartInitException e) { IStatus errorStatus = StatusFactory.errorStatus(pluginId, NLS.bind("Could not open browser for url \"{0}\".", url), e); log.log(errorStatus); } } public void checkedCreateExternalBrowser(String url, String pluginId, ILog log) { try { openUrl(url, PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser(), pluginId, log); } catch (PartInitException e) { IStatus errorStatus = StatusFactory.errorStatus(pluginId, NLS.bind("Could not open browser for url \"{0}\".", url), e); log.log(errorStatus); } } public void openUrl(String url, IWebBrowser browser, String pluginId, ILog log) { try { browser.openURL(new URL(url)); } catch (PartInitException e) { IStatus errorStatus = StatusFactory.errorStatus(pluginId, NLS.bind("Could not open browser for url \"{0}\".", url), e); log.log(errorStatus); } catch (MalformedURLException e) { IStatus errorStatus = StatusFactory.errorStatus(pluginId, NLS.bind("Could not display malformed url \"{0}\".", url), e); log.log(errorStatus); } } public void openExtenalBrowser(String URL) { checkedCreateExternalBrowser(URL,FoundationUIPlugin.PLUGIN_ID,FoundationUIPlugin.getDefault().getLog()); } /** * Creates an SWT Browser * @param style * @param parent * @return */ public Browser createBrowser(int style, Composite parent) { return createBrowser(style, parent, getPreferredBrowser()); } /** * Creates an SWT Browser * @param parent * @param preferredBrowser SWT.MOZILLA, SWT.WEBKIT or SWT.NONE * @return */ public Browser createBrowser(Composite parent) { return createBrowser(SWT.READ_ONLY | SWT.NO_SCROLL, parent, getPreferredBrowser()); } /** * Creates an SWT Browser * @param parent * @param preferredBrowser SWT.MOZILLA, SWT.WEBKIT or SWT.NONE * @return */ public Browser createBrowser(Composite parent, int preferredBrowser) { return createBrowser(SWT.READ_ONLY | SWT.NO_SCROLL, parent, preferredBrowser); } /** * Creates an SWT Browser. Returns null if can't create a browser. * @param style * @param parent * @param preferredBrowser SWT.MOZILLA, SWT.WEBKIT or SWT.NONE * @return * @see org.eclipse.swt.browser.Browser */ public Browser createBrowser(int style, Composite parent, int preferredBrowser) { return createBrowser(style, parent, preferredBrowser, true); } private Browser createBrowser(int style, Composite parent, int preferredBrowser, boolean logError) { /* // We can provide webkit in this way: String defaultBrowser = System.getProperty(Browser.PROPERTY_DEFAULTTYPE); boolean hasDefaultBrowser = defaultBrowser != null; System.getProperties().setProperty(Browser.PROPERTY_DEFAULTTYPE, "webkit"); */ String val = System.getProperty("jbosstools.skip.browser.creation"); if(val!=null) { boolean skip = Boolean.parseBoolean(val); if( skip ) return null; } try { try { return new Browser(parent, style | preferredBrowser); } catch (SWTError e) { boolean preLogged = browserLoadingErrorLoged; if(!preLogged && logError) { logBrowserLoadingProblem(e, browserNames.get(preferredBrowser), true); } Control[] children = parent.getChildren(); for (Control child : children) { child.dispose(); } try { return new Browser(parent, style | SWT.NONE); } catch (SWTError e1) { if( !preLogged && logError ) logBrowserLoadingProblem(e1, null, false); Control[] children1 = parent.getChildren(); for (Control child : children1) { child.dispose(); } } } } finally { /* //Use if system property was modified if(hasDefaultBrowser) { System.getProperties().setProperty(property, defaultBrowser); } */ } return null; } public Control createBrowserOrLink(int style, Composite parent, int preferredBrowser, String url, String noBrowserText, Menu contextMenu) { Control result = createBrowserOrLink(style, parent, preferredBrowser, url, noBrowserText); result.setMenu(createLinkDefaultContextMenu(result, url)); return result; } /** * Return either a browser, or a link (if no browser can be created) * * @param style * @param parent * @param preferredBrowser * @param URL * @param noBrowserText * @return */ public Control createBrowserOrLink(int style, Composite parent, int preferredBrowser, final String url, String noBrowserText) { return createBrowserOrLink(style, parent, preferredBrowser, new IURLProvider() { public String getUrl() { return url; } }, noBrowserText); } public Control createBrowserOrLink(int style, Composite parent, IURLProvider url, String noBrowserText) { return createBrowserOrLink(style, parent, getPreferredBrowser(), url, noBrowserText); } public Control createBrowserOrLink(int style, Composite parent, int preferredBrowser, IURLProvider url, String noBrowserText) { Control result = null; Browser browser = createBrowser(style, parent, preferredBrowser, false); if (browser == null) { //TODO: Implement loading for .txt files and showing them in // link as a text with visible hyperlink to open original address final Link link = new Link(parent, SWT.NONE); link.setText(noBrowserText); SelectionListener openExBrowser = new OpenExBrowserListener(url); link.addSelectionListener(openExBrowser); result = link; } else { result = browser; } return result; } private Menu createLinkDefaultContextMenu (Control link, String url) { Menu popupMenu = new Menu(link); MenuItem refreshItem = new MenuItem(popupMenu, SWT.NONE); refreshItem.setText(BrowserUtilityMessages.Open_in_external_browser); refreshItem.addSelectionListener(new OpenExBrowserListener(url)); MenuItem copyToClipboard = new MenuItem(popupMenu, SWT.NONE); copyToClipboard.setText(BrowserUtilityMessages.Copy_URL_to_clipboard); copyToClipboard.addSelectionListener(new CopyToClipboardListener(url)); link.setMenu(popupMenu); return popupMenu; } private static void logBrowserLoadingProblem(Error e, String browserName, boolean warning) { Exception e2 = new Exception(e); if(browserName==null) { browserName = "default"; } String message = "Cannot create " + browserName + " browser"; if(warning) { FoundationUIPlugin.pluginLog().logWarning(message,e2); } else { FoundationUIPlugin.pluginLog().logError(message, e2); } browserLoadingErrorLoged = true; } protected static final boolean isMacOS = "Mac OS X".equals(System.getProperty("os.name")); public static int getPreferredBrowser() { return isMacOS ? SWT.WEBKIT : SWT.MOZILLA; } public class OpenExBrowserListener extends SelectionAdapter { private String url; private IURLProvider provider; public OpenExBrowserListener(String url) { this.url = url; } public OpenExBrowserListener(IURLProvider provider) { this.provider = provider; } public void widgetSelected(SelectionEvent event) { if( url != null ) { BrowserUtility.this.openExtenalBrowser(url); } else { BrowserUtility.this.openExtenalBrowser(provider.getUrl()); } } } private static class CopyToClipboardListener extends SelectionAdapter { private String url; private Clipboard cb = new Clipboard(Display.getCurrent()); public CopyToClipboardListener(String url) { this.url = url; } @Override public void widgetSelected(SelectionEvent e) { TextTransfer textTransfer = TextTransfer.getInstance(); cb.setContents(new Object[] { url }, new Transfer[] { textTransfer }); } } }