/* * Copyright (c) 2012, grossmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the jo-widgets.org nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.jowidgets.addons.widgets.browser.impl.swt; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Set; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.BrowserFunction; import org.eclipse.swt.browser.LocationEvent; import org.eclipse.swt.browser.LocationListener; import org.eclipse.swt.browser.ProgressEvent; import org.eclipse.swt.browser.ProgressListener; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.jowidgets.addons.widgets.browser.api.IBrowser; import org.jowidgets.addons.widgets.browser.api.IBrowserFunction; import org.jowidgets.addons.widgets.browser.api.IBrowserFunctionHandle; import org.jowidgets.addons.widgets.browser.api.IBrowserLocationEvent; import org.jowidgets.addons.widgets.browser.api.IBrowserLocationListener; import org.jowidgets.addons.widgets.browser.api.IBrowserProgressListener; import org.jowidgets.addons.widgets.browser.api.IBrowserSetupBuilder; import org.jowidgets.api.toolkit.Toolkit; import org.jowidgets.api.widgets.IControl; import org.jowidgets.api.widgets.IWindow; import org.jowidgets.spi.impl.swt.common.color.ColorCache; import org.jowidgets.tools.types.VetoHolder; import org.jowidgets.tools.widgets.wrapper.ControlWrapper; import org.jowidgets.util.Assert; import net.miginfocom.swt.MigLayout; class BrowserImpl extends ControlWrapper implements IBrowser { private final Set<IBrowserLocationListener> locationListeners; private final Set<IBrowserProgressListener> progressListeners; private final Browser swtBrowser; BrowserImpl(final IControl control, final Composite swtComposite, final IBrowserSetupBuilder<?> setup) { super(control); this.locationListeners = new LinkedHashSet<IBrowserLocationListener>(); this.progressListeners = new LinkedHashSet<IBrowserProgressListener>(); final Composite content; if (setup.hasBorder()) { swtComposite.setLayout(new FillLayout()); content = new Composite(swtComposite, SWT.BORDER); } else { content = swtComposite; } content.setLayout(new MigLayout("", "0[grow, 0::]0", "0[grow, 0::]0")); content.addControlListener(new ControlAdapter() { @Override public void controlResized(final ControlEvent e) { final IWindow activeWindow = Toolkit.getActiveWindow(); if (activeWindow != null) { activeWindow.redraw(); } } }); this.swtBrowser = new Browser(content, SWT.NONE); swtBrowser.setLayoutData("growx, growy, w 0::, h 0::"); swtBrowser.addLocationListener(new LocationListenerImpl()); swtBrowser.addProgressListener(new ProgressListenerImpl()); if (setup.isVisible() != null) { setVisible(setup.isVisible().booleanValue()); } if (setup.getBackgroundColor() != null) { swtBrowser.setBackground(ColorCache.getInstance().getColor(setup.getBackgroundColor())); } if (setup.getForegroundColor() != null) { swtBrowser.setForeground(ColorCache.getInstance().getColor(setup.getForegroundColor())); } } final Browser getSwtBrowser() { return swtBrowser; } @Override public final void setUrl(String url) { if (url == null) { url = ""; } swtBrowser.setText(""); swtBrowser.setUrl(url); } @Override public final void setHtml(String html) { if (html == null) { html = ""; } swtBrowser.setUrl(""); swtBrowser.setText(html); } @Override public final Object evaluateScript(final String javaScript) { Assert.paramNotNull(javaScript, "javaScript"); return swtBrowser.evaluate(javaScript); } @Override public final boolean executeScript(final String javaScript) { Assert.paramNotNull(javaScript, "javaScript"); return swtBrowser.execute(javaScript); } @Override public IBrowserFunctionHandle createBrowserFunction(final String functionName, final IBrowserFunction function) { Assert.paramNotEmpty(functionName, "functionName"); Assert.paramNotNull(function, "function"); return new BrowserFunctionHandle(functionName, new BrowserFunctionAdapter(getSwtBrowser(), functionName, function)); } @Override public final void addLocationListener(final IBrowserLocationListener listener) { Assert.paramNotNull(listener, "listener"); locationListeners.add(listener); } @Override public final void removeLocationListener(final IBrowserLocationListener listener) { Assert.paramNotNull(listener, "listener"); locationListeners.remove(listener); } @Override public final void addProgressListener(final IBrowserProgressListener listener) { Assert.paramNotNull(listener, "listener"); progressListeners.add(listener); } @Override public final void removeProgressListener(final IBrowserProgressListener listener) { Assert.paramNotNull(listener, "listener"); progressListeners.remove(listener); } private final class LocationListenerImpl implements LocationListener { @Override public void changing(final LocationEvent event) { if (fireOnLocationChange(event)) { event.doit = false; } } @Override public void changed(final LocationEvent event) { fireLocationChanged(event); } /** * Fires an on location change event. * * @param swtEvent * @return true, if a veto occurred */ private boolean fireOnLocationChange(final LocationEvent swtEvent) { if (locationListeners.size() > 0) { final IBrowserLocationEvent event = new BrowserLocationEvent(swtEvent); final VetoHolder vetoHolder = new VetoHolder(); for (final IBrowserLocationListener listener : new LinkedList<IBrowserLocationListener>(locationListeners)) { listener.onLocationChange(event, vetoHolder); if (vetoHolder.hasVeto()) { return true; } } } return false; } private void fireLocationChanged(final LocationEvent swtEvent) { if (locationListeners.size() > 0) { final IBrowserLocationEvent event = new BrowserLocationEvent(swtEvent); for (final IBrowserLocationListener listener : new LinkedList<IBrowserLocationListener>(locationListeners)) { listener.locationChanged(event); } } } } private final class ProgressListenerImpl implements ProgressListener { @Override public void changed(final ProgressEvent event) { for (final IBrowserProgressListener listener : new LinkedList<IBrowserProgressListener>(progressListeners)) { listener.loadProgressChanged(event.current, event.total); } } @Override public void completed(final ProgressEvent event) { for (final IBrowserProgressListener listener : new LinkedList<IBrowserProgressListener>(progressListeners)) { listener.loadFinished(); } } } private final class BrowserFunctionAdapter extends BrowserFunction { private final IBrowserFunction function; BrowserFunctionAdapter(final Browser browser, final String functionName, final IBrowserFunction function) { super(browser, functionName); this.function = function; } @Override public Object function(final Object[] arguments) { return function.invoke(arguments); } } private final class BrowserFunctionHandle implements IBrowserFunctionHandle { private final String functionName; private final BrowserFunction browserFunction; private BrowserFunctionHandle(final String functionName, final BrowserFunction browserFunction) { this.functionName = functionName; this.browserFunction = browserFunction; } @Override public void dispose() { browserFunction.dispose(); } @Override public boolean isDisposed() { return browserFunction.isDisposed(); } @Override public String getFunctionName() { return functionName; } } }