Index: tmp/org.txm.libs.javafx/swt/JFXBrowserViewer.java
===================================================================
--- tmp/org.txm.libs.javafx/swt/JFXBrowserViewer.java	(revision 0)
+++ tmp/org.txm.libs.javafx/swt/JFXBrowserViewer.java	(revision 3108)
@@ -0,0 +1,915 @@
+package snippet;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.SWTException;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.LocationAdapter;
+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.browser.VisibilityWindowAdapter;
+import org.eclipse.swt.browser.WindowEvent;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.events.MouseAdapter;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.internal.browser.BusyIndicator;
+import org.eclipse.ui.internal.browser.ContextIds;
+import org.eclipse.ui.internal.browser.IBrowserViewerContainer;
+import org.eclipse.ui.internal.browser.ImageResource;
+import org.eclipse.ui.internal.browser.ToolbarLayout;
+import org.eclipse.ui.internal.browser.Trace;
+import org.eclipse.ui.internal.browser.WebBrowserPreference;
+import org.eclipse.ui.internal.browser.WebBrowserUtil;
+import org.txm.rcp.commands.OpenLocalizedWebPage;
+import org.txm.rcp.swt.JFXBrowser;
+
+/**
+ * A Web browser widget. It extends the Eclipse SWT Browser widget by adding an
+ * optional toolbar complete with a URL combo box, history, back & forward, and
+ * refresh buttons.
+ * <p>
+ * Use the style bits to choose which toolbars are available within the browser
+ * composite. You can access the embedded SWT Browser directly using the
+ * getBrowser() method.
+ * </p>
+ * <p>
+ * Additional capabilities are available when used as the internal Web browser,
+ * including status text and progress on the Eclipse window's status line, or
+ * moving the toolbar capabilities up into the main toolbar.
+ * </p>
+ * <dl>
+ * <dt><b>Styles:</b></dt>
+ * <dd>LOCATION_BAR, BUTTON_BAR</dd>
+ * <dt><b>Events:</b></dt>
+ * <dd>None</dd>
+ * </dl>
+ *
+ * @since 1.0
+ */
+public class JFXBrowserViewer extends Composite {
+	
+	/**
+	 * Style parameter (value 1) indicating that the URL and Go button will be
+	 * on the local toolbar.
+	 */
+	public static final int LOCATION_BAR = 1 << 1;
+	
+	/**
+	 * Style parameter (value 2) indicating that the toolbar will be available
+	 * on the web browser. This style parameter cannot be used without the
+	 * LOCATION_BAR style.
+	 */
+	public static final int BUTTON_BAR = 1 << 2;
+	
+	protected static final String PROPERTY_TITLE = "title"; //$NON-NLS-1$
+	
+	private static final int MAX_HISTORY = 50;
+	
+	public Clipboard clipboard;
+	
+	public Combo combo;
+	
+	protected boolean showToolbar;
+	
+	protected boolean showURLbar;
+	
+	protected ToolItem back;
+	
+	protected ToolItem forward;
+	
+	protected BusyIndicator busy;
+	
+	protected boolean loading;
+	
+	protected static java.util.List<String> history;
+	
+	protected JFXBrowser browser;
+	
+	protected JFXBrowserText text;
+	
+	protected boolean newWindow;
+	
+	protected IBrowserViewerContainer container;
+	
+	protected String title;
+	
+	protected int progressWorked = 0;
+	
+	protected List<PropertyChangeListener> propertyListeners;
+	
+	/**
+	 * Under development - do not use
+	 */
+	public static interface ILocationListener {
+		
+		public void locationChanged(String url);
+		
+		public void historyChanged(String[] history2);
+	}
+	
+	public ILocationListener locationListener;
+	
+	/**
+	 * Under development - do not use
+	 */
+	public static interface IBackNextListener {
+		
+		public void updateBackNextBusy();
+	}
+	
+	public IBackNextListener backNextListener;
+	
+	/**
+	 * Creates a new Web browser given its parent and a style value describing
+	 * its behavior and appearance.
+	 * <p>
+	 * The style value is either one of the style constants defined in the class
+	 * header or class <code>SWT</code> which is applicable to instances of
+	 * this class, or must be built by <em>bitwise OR</em>'ing together (that
+	 * is, using the <code>int</code> "|" operator) two or more of those
+	 * <code>SWT</code> style constants. The class description lists the style
+	 * constants that are applicable to the class. Style bits are also inherited
+	 * from superclasses.
+	 * </p>
+	 *
+	 * @param parent
+	 *            a composite control which will be the parent of the new
+	 *            instance (cannot be null)
+	 * @param style
+	 *            the style of control to construct
+	 */
+	public JFXBrowserViewer(Composite parent, int style) {
+		super(parent, SWT.NONE);
+		
+		if ((style & LOCATION_BAR) != 0)
+			showURLbar = true;
+		
+		if ((style & BUTTON_BAR) != 0)
+			showToolbar = true;
+		
+		GridLayout layout = new GridLayout();
+		layout.marginHeight = 0;
+		layout.marginWidth = 0;
+		layout.horizontalSpacing = 0;
+		layout.verticalSpacing = 0;
+		layout.numColumns = 1;
+		setLayout(layout);
+		setLayoutData(new GridData(GridData.FILL_BOTH));
+		clipboard = new Clipboard(parent.getDisplay());
+		
+		if (showToolbar || showURLbar) {
+			Composite toolbarComp = new Composite(this, SWT.NONE);
+			toolbarComp.setLayout(new ToolbarLayout());
+			toolbarComp.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL));
+			
+			if (showToolbar)
+				createToolbar(toolbarComp);
+			
+			if (showURLbar)
+				createLocationBar(toolbarComp);
+			
+			if (showToolbar | showURLbar) {
+				busy = new BusyIndicator(toolbarComp, SWT.NONE);
+				busy.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+				busy.addMouseListener(new MouseAdapter() {
+					
+					@Override
+					public void mouseDown(MouseEvent e) {
+						setURL(OpenLocalizedWebPage.URL_TEXTOMETRIE);
+					}
+				});
+			}
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(this, ContextIds.WEB_BROWSER);
+		}
+		
+		// create a new SWT Web browser widget, checking once again to make sure
+		// we can use it in this environment
+		// if (WebBrowserUtil.canUseInternalWebBrowser())
+		try {
+			this.browser = new JFXBrowser(this, SWT.NONE);
+		}
+		catch (SWTError e) {
+			if (e.code != SWT.ERROR_NO_HANDLES) {
+				WebBrowserUtil.openError(org.eclipse.ui.internal.browser.Messages.errorCouldNotLaunchInternalWebBrowser);
+				return;
+			}
+			text = new JFXBrowserText(this, this, e);
+		}
+		
+		if (showURLbar)
+			updateHistory();
+		if (showToolbar)
+			updateBackNextBusy();
+		
+		if (browser != null) {
+			browser.setLayoutData(new GridData(GridData.FILL_BOTH));
+			PlatformUI.getWorkbench().getHelpSystem().setHelp(browser,
+					ContextIds.WEB_BROWSER);
+		}
+		else
+			text.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
+		
+		addBrowserListeners();
+		// listen();
+	}
+	
+	/**
+	 * Returns the underlying SWT browser widget.
+	 *
+	 * @return the underlying browser
+	 */
+	public JFXBrowser getBrowser() {
+		return browser;
+	}
+	
+	/**
+	 * Navigate to the home URL.
+	 */
+	public void home() {
+		System.out.println("JFXBrowserViewer.home()");
+		// browser.getWebView().setH.set.setText(""); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Loads a URL.
+	 *
+	 * @param url
+	 *            the URL to be loaded
+	 * @return true if the operation was successful and false otherwise.
+	 * @exception IllegalArgumentException
+	 *                <ul>
+	 *                <li>ERROR_NULL_ARGUMENT - if the url is null</li>
+	 *                </ul>
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS when called from the
+	 *                wrong thread</li>
+	 *                <li>ERROR_WIDGET_DISPOSED when the widget has been
+	 *                disposed</li>
+	 *                </ul>
+	 * @see #getURL()
+	 */
+	public void setURL(String url) {
+		setURL(url, true);
+	}
+	
+	protected void updateBackNextBusy() {
+		if (!back.isDisposed()) {
+			back.setEnabled(isBackEnabled());
+		}
+		if (!forward.isDisposed()) {
+			forward.setEnabled(isForwardEnabled());
+		}
+		if (!busy.isDisposed()) {
+			busy.setBusy(loading);
+		}
+		
+		if (backNextListener != null)
+			backNextListener.updateBackNextBusy();
+	}
+	
+	protected void updateLocation() {
+		if (locationListener != null)
+			locationListener.historyChanged(null);
+		
+		if (locationListener != null)
+			locationListener.locationChanged(null);
+	}
+	
+	/**
+	 *
+	 */
+	private void addBrowserListeners() {
+		if (browser == null) return;
+		// respond to ExternalBrowserInstance StatusTextEvents events by
+		// updating the status line
+		browser.addStatusTextListener(event -> {
+			// System.out.println("status: " + event.text); //$NON-NLS-1$
+			if (container != null) {
+				IStatusLineManager status = container.getActionBars().getStatusLineManager();
+				status.setMessage(event.text);
+			}
+		});
+		
+		// Add listener for new window creation so that we can instead of
+		// opening a separate
+		// new window in which the session is lost, we can instead open a new
+		// window in a new
+		// shell within the browser area thereby maintaining the session.
+		browser.addOpenWindowListener(event -> {
+			Shell shell2 = new Shell(getShell(), SWT.SHELL_TRIM);
+			shell2.setLayout(new FillLayout());
+			shell2.setText(org.eclipse.ui.internal.browser.Messages.viewWebBrowserTitle);
+			shell2.setImage(getShell().getImage());
+			if (event.location != null)
+				shell2.setLocation(event.location);
+			if (event.size != null)
+				shell2.setSize(event.size);
+			int style = 0;
+			if (showURLbar)
+				style += LOCATION_BAR;
+			if (showToolbar)
+				style += BUTTON_BAR;
+			JFXBrowserViewer browser2 = new JFXBrowserViewer(shell2, style);
+			browser2.newWindow = true;
+			event.browser = null; // TODO should be browser2
+		});
+		
+		browser.addVisibilityWindowListener(new VisibilityWindowAdapter() {
+			
+			@Override
+			public void show(WindowEvent e) {
+				Browser browser2 = (Browser) e.widget;
+				if (browser2.getParent().getParent() instanceof Shell) {
+					Shell shell = (Shell) browser2.getParent().getParent();
+					if (e.location != null)
+						shell.setLocation(e.location);
+					if (e.size != null)
+						shell.setSize(shell.computeSize(e.size.x, e.size.y));
+					shell.open();
+				}
+			}
+		});
+		
+		browser.addCloseWindowListener(event -> {
+			// if shell is not null, it must be a secondary popup window,
+			// else its an editor window
+			if (newWindow)
+				getShell().dispose();
+			else
+				container.close();
+		});
+		
+		browser.addProgressListener(new ProgressListener() {
+			
+			@Override
+			public void changed(ProgressEvent event) {
+				// System.out.println("progress: " + event.current + ", " + event.total); //$NON-NLS-1$ //$NON-NLS-2$
+				if (event.total == 0)
+					return;
+				
+				boolean done = (event.current == event.total);
+				
+				int percentProgress = event.current * 100 / event.total;
+				if (container != null) {
+					IProgressMonitor monitor = container.getActionBars()
+							.getStatusLineManager().getProgressMonitor();
+					if (done) {
+						monitor.done();
+						progressWorked = 0;
+					}
+					else if (progressWorked == 0) {
+						monitor.beginTask("", event.total); //$NON-NLS-1$
+						progressWorked = percentProgress;
+					}
+					else {
+						monitor.worked(event.current - progressWorked);
+						progressWorked = event.current;
+					}
+				}
+				
+				if (showToolbar) {
+					if (!busy.isBusy() && !done)
+						loading = true;
+					else if (busy.isBusy() && done) // once the progress hits
+						// 100 percent, done, set
+						// busy to false
+						loading = false;
+					
+					// System.out.println("loading: " + loading); //$NON-NLS-1$
+					updateBackNextBusy();
+					updateHistory();
+				}
+			}
+			
+			@Override
+			public void completed(ProgressEvent event) {
+				if (container != null) {
+					IProgressMonitor monitor = container.getActionBars()
+							.getStatusLineManager().getProgressMonitor();
+					monitor.done();
+				}
+				if (showToolbar) {
+					loading = false;
+					updateBackNextBusy();
+					updateHistory();
+				}
+			}
+		});
+		
+		if (showURLbar) {
+			browser.addLocationListener(new LocationAdapter() {
+				
+				@Override
+				public void changed(LocationEvent event) {
+					if (!event.top)
+						return;
+					if (combo != null) {
+						if (!"about:blank".equals(event.location)) { //$NON-NLS-1$
+							combo.setText(event.location);
+							addToHistory(event.location);
+							updateHistory();
+						}// else
+							// combo.setText(""); //$NON-NLS-1$
+					}
+				}
+			});
+		}
+		
+		browser.addTitleListener(event -> {
+			String oldTitle = title;
+			title = event.title;
+			firePropertyChangeEvent(PROPERTY_TITLE, oldTitle, title);
+		});
+	}
+	
+	/**
+	 * Add a property change listener to this instance.
+	 *
+	 * @param listener java.beans.PropertyChangeListener
+	 */
+	public void addPropertyChangeListener(PropertyChangeListener listener) {
+		if (propertyListeners == null)
+			propertyListeners = new ArrayList<>();
+		propertyListeners.add(listener);
+	}
+	
+	/**
+	 * Remove a property change listener from this instance.
+	 *
+	 * @param listener java.beans.PropertyChangeListener
+	 */
+	public void removePropertyChangeListener(PropertyChangeListener listener) {
+		if (propertyListeners != null)
+			propertyListeners.remove(listener);
+	}
+	
+	/**
+	 * Fire a property change event.
+	 */
+	protected void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) {
+		if (propertyListeners == null)
+			return;
+		
+		PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
+		// Trace.trace("Firing: " + event + " " + oldValue);
+		try {
+			int size = propertyListeners.size();
+			PropertyChangeListener[] pcl = new PropertyChangeListener[size];
+			propertyListeners.toArray(pcl);
+			
+			for (int i = 0; i < size; i++)
+				try {
+					pcl[i].propertyChange(event);
+				}
+				catch (Exception e) {
+					// ignore
+				}
+		}
+		catch (Exception e) {
+			// ignore
+		}
+	}
+	
+	/**
+	 * Navigate to the next session history item. Convenience method that calls
+	 * the underlying SWT browser.
+	 *
+	 * @return <code>true</code> if the operation was successful and
+	 *         <code>false</code> otherwise
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS when called from the
+	 *                wrong thread</li>
+	 *                <li>ERROR_WIDGET_DISPOSED when the widget has been
+	 *                disposed</li>
+	 *                </ul>
+	 * @see #back
+	 */
+	public boolean forward() {
+		if (browser == null)
+			return false;
+		return browser.forward();
+	}
+	
+	/**
+	 * Navigate to the previous session history item. Convenience method that
+	 * calls the underlying SWT browser.
+	 *
+	 * @return <code>true</code> if the operation was successful and
+	 *         <code>false</code> otherwise
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS when called from the
+	 *                wrong thread</li>
+	 *                <li>ERROR_WIDGET_DISPOSED when the widget has been
+	 *                disposed</li>
+	 *                </ul>
+	 * @see #forward
+	 */
+	public boolean back() {
+		if (browser == null)
+			return false;
+		return browser.back();
+	}
+	
+	/**
+	 * Returns <code>true</code> if the receiver can navigate to the previous
+	 * session history item, and <code>false</code> otherwise. Convenience
+	 * method that calls the underlying SWT browser.
+	 *
+	 * @return the receiver's back command enabled state
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+	 *                disposed</li>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+	 *                thread that created the receiver</li>
+	 *                </ul>
+	 * @see #back
+	 */
+	public boolean isBackEnabled() {
+		if (browser == null)
+			return false;
+		return browser.isBackEnabled();
+	}
+	
+	/**
+	 * Returns <code>true</code> if the receiver can navigate to the next
+	 * session history item, and <code>false</code> otherwise. Convenience
+	 * method that calls the underlying SWT browser.
+	 *
+	 * @return the receiver's forward command enabled state
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
+	 *                disposed</li>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
+	 *                thread that created the receiver</li>
+	 *                </ul>
+	 * @see #forward
+	 */
+	public boolean isForwardEnabled() {
+		if (browser == null)
+			return false;
+		return browser.isForwardEnabled();
+	}
+	
+	/**
+	 * Stop any loading and rendering activity. Convenience method that calls
+	 * the underlying SWT browser.
+	 *
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS when called from the
+	 *                wrong thread</li>
+	 *                <li>ERROR_WIDGET_DISPOSED when the widget has been
+	 *                disposed</li>
+	 *                </ul>
+	 */
+	public void stop() {
+		if (browser != null)
+			browser.stop();
+	}
+	
+	/**
+	 *
+	 */
+	private boolean navigate(String url) {
+		Trace.trace(Trace.FINER, "Navigate: " + url); //$NON-NLS-1$
+		if (url != null && url.equals(getURL())) {
+			refresh();
+			return true;
+		}
+		if (browser != null)
+			return browser.setUrl(url, null, new String[] { "Cache-Control: no-cache" }); //$NON-NLS-1$
+		return text.setUrl(url);
+	}
+	
+	/**
+	 * Refresh the current page. Convenience method that calls the underlying
+	 * SWT browser.
+	 *
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS when called from the
+	 *                wrong thread</li>
+	 *                <li>ERROR_WIDGET_DISPOSED when the widget has been
+	 *                disposed</li>
+	 *                </ul>
+	 */
+	public void refresh() {
+		if (browser != null)
+			browser.refresh();
+		else
+			text.refresh();
+		try {
+			Thread.sleep(50);
+		}
+		catch (Exception e) {
+			// ignore
+		}
+	}
+	
+	private void setURL(String url, boolean browse) {
+		Trace.trace(Trace.FINEST, "setURL: " + url + " " + browse); //$NON-NLS-1$ //$NON-NLS-2$
+		if (url == null) {
+			home();
+			return;
+		}
+		
+		if (browse)
+			navigate(url);
+		
+		addToHistory(url);
+		updateHistory();
+	}
+	
+	protected void addToHistory(String url) {
+		if (history == null)
+			history = WebBrowserPreference.getInternalWebBrowserHistory();
+		int found = -1;
+		int size = history.size();
+		for (int i = 0; i < size; i++) {
+			String s = history.get(i);
+			if (s.equals(url)) {
+				found = i;
+				break;
+			}
+		}
+		
+		if (found == -1) {
+			if (size >= MAX_HISTORY)
+				history.remove(size - 1);
+			history.add(0, url);
+			WebBrowserPreference.setInternalWebBrowserHistory(history);
+		}
+		else if (found != 0) {
+			history.remove(found);
+			history.add(0, url);
+			WebBrowserPreference.setInternalWebBrowserHistory(history);
+		}
+	}
+	
+	/**
+	 *
+	 */
+	@Override
+	public void dispose() {
+		super.dispose();
+		
+		showToolbar = false;
+		
+		if (busy != null)
+			busy.dispose();
+		busy = null;
+		
+		browser = null;
+		text = null;
+		if (clipboard != null)
+			clipboard.dispose();
+		clipboard = null;
+		
+		removeSynchronizationListener();
+	}
+	
+	private ToolBar createLocationBar(Composite parent) {
+		combo = new Combo(parent, SWT.DROP_DOWN);
+		
+		updateHistory();
+		
+		combo.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
+			try {
+				if (combo.getSelectionIndex() != -1 && !combo.getListVisible()) {
+					setURL(combo.getItem(combo.getSelectionIndex()));
+				}
+			}
+			catch (Exception e1) {
+				// ignore
+			}
+		}));
+		combo.addListener(SWT.DefaultSelection, e -> setURL(combo.getText()));
+		
+		ToolBar toolbar = new ToolBar(parent, SWT.FLAT);
+		
+		ToolItem go = new ToolItem(toolbar, SWT.NONE);
+		go.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_GO));
+		go.setHotImage(ImageResource.getImage(ImageResource.IMG_CLCL_NAV_GO));
+		go.setDisabledImage(ImageResource
+				.getImage(ImageResource.IMG_DLCL_NAV_GO));
+		go.setToolTipText(org.eclipse.ui.internal.browser.Messages.actionWebBrowserGo);
+		go.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> setURL(combo.getText())));
+		
+		return toolbar;
+	}
+	
+	private ToolBar createToolbar(Composite parent) {
+		ToolBar toolbar = new ToolBar(parent, SWT.FLAT);
+		
+		// create back and forward actions
+		back = new ToolItem(toolbar, SWT.NONE);
+		back.setImage(ImageResource
+				.getImage(ImageResource.IMG_ELCL_NAV_BACKWARD));
+		back.setHotImage(ImageResource
+				.getImage(ImageResource.IMG_CLCL_NAV_BACKWARD));
+		back.setDisabledImage(ImageResource
+				.getImage(ImageResource.IMG_DLCL_NAV_BACKWARD));
+		back.setToolTipText(org.eclipse.ui.internal.browser.Messages.actionWebBrowserBack);
+		back.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> back()));
+		
+		forward = new ToolItem(toolbar, SWT.NONE);
+		forward.setImage(ImageResource
+				.getImage(ImageResource.IMG_ELCL_NAV_FORWARD));
+		forward.setHotImage(ImageResource
+				.getImage(ImageResource.IMG_CLCL_NAV_FORWARD));
+		forward.setDisabledImage(ImageResource
+				.getImage(ImageResource.IMG_DLCL_NAV_FORWARD));
+		forward.setToolTipText(org.eclipse.ui.internal.browser.Messages.actionWebBrowserForward);
+		forward.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> forward()));
+		
+		// create refresh, stop, and print actions
+		ToolItem stop = new ToolItem(toolbar, SWT.NONE);
+		stop.setImage(ImageResource.getImage(ImageResource.IMG_ELCL_NAV_STOP));
+		stop.setHotImage(ImageResource
+				.getImage(ImageResource.IMG_CLCL_NAV_STOP));
+		stop.setDisabledImage(ImageResource
+				.getImage(ImageResource.IMG_DLCL_NAV_STOP));
+		stop.setToolTipText(org.eclipse.ui.internal.browser.Messages.actionWebBrowserStop);
+		stop.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> stop()));
+		
+		ToolItem refresh = new ToolItem(toolbar, SWT.NONE);
+		refresh.setImage(ImageResource
+				.getImage(ImageResource.IMG_ELCL_NAV_REFRESH));
+		refresh.setHotImage(ImageResource
+				.getImage(ImageResource.IMG_CLCL_NAV_REFRESH));
+		refresh.setDisabledImage(ImageResource
+				.getImage(ImageResource.IMG_DLCL_NAV_REFRESH));
+		refresh.setToolTipText(org.eclipse.ui.internal.browser.Messages.actionWebBrowserRefresh);
+		refresh.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> refresh()));
+		
+		return toolbar;
+	}
+	
+	/**
+	 * Returns the current URL. Convenience method that calls the underlying SWT
+	 * browser.
+	 *
+	 * @return the current URL or an empty <code>String</code> if there is no
+	 *         current URL
+	 * @exception SWTException
+	 *                <ul>
+	 *                <li>ERROR_THREAD_INVALID_ACCESS when called from the
+	 *                wrong thread</li>
+	 *                <li>ERROR_WIDGET_DISPOSED when the widget has been
+	 *                disposed</li>
+	 *                </ul>
+	 * @see #setURL(String)
+	 */
+	public String getURL() {
+		if (browser != null)
+			return browser.getUrl();
+		return text.getUrl();
+	}
+	
+	@Override
+	public boolean setFocus() {
+		if (browser != null) {
+			browser.setFocus();
+			updateHistory();
+			return true;
+		}
+		return super.setFocus();
+	}
+	
+	/**
+	 * Update the history list to the global/shared copy.
+	 */
+	protected void updateHistory() {
+		if (combo == null || combo.isDisposed())
+			return;
+		
+		String temp = combo.getText();
+		if (history == null)
+			history = WebBrowserPreference.getInternalWebBrowserHistory();
+		
+		String[] historyList = new String[history.size()];
+		history.toArray(historyList);
+		combo.setItems(historyList);
+		
+		combo.setText(temp);
+	}
+	
+	public IBrowserViewerContainer getContainer() {
+		return container;
+	}
+	
+	public void setContainer(IBrowserViewerContainer container) {
+		if (container == null && this.container != null) {
+			IStatusLineManager manager = this.container.getActionBars().getStatusLineManager();
+			if (manager != null)
+				manager.getProgressMonitor().done();
+		}
+		this.container = container;
+	}
+	
+	protected File file;
+	
+	protected long timestamp;
+	
+	protected Thread fileListenerThread;
+	
+	protected LocationListener locationListener2;
+	
+	protected Object syncObject = new Object();
+	
+	protected void addSynchronizationListener() {
+		if (fileListenerThread != null)
+			return;
+		
+		fileListenerThread = new Thread("Browser file synchronization") { //$NON-NLS-1$
+			
+			@Override
+			public void run() {
+				while (fileListenerThread != null) {
+					try {
+						Thread.sleep(2000);
+					}
+					catch (Exception e) {
+						// ignore
+					}
+					synchronized (syncObject) {
+						if (file != null && file.lastModified() != timestamp) {
+							timestamp = file.lastModified();
+							Display.getDefault().syncExec(() -> refresh());
+						}
+					}
+				}
+			}
+		};
+		fileListenerThread.setDaemon(true);
+		fileListenerThread.setPriority(Thread.MIN_PRIORITY);
+		
+		locationListener2 = new LocationAdapter() {
+			
+			@Override
+			public void changed(LocationEvent event) {
+				File temp = getFile(event.location);
+				if (temp != null && temp.exists()) {
+					synchronized (syncObject) {
+						file = temp;
+						timestamp = file.lastModified();
+					}
+				}
+				else
+					file = null;
+			}
+		};
+		browser.addLocationListener(locationListener2);
+		
+		File temp = getFile(browser.getUrl());
+		if (temp != null && temp.exists()) {
+			file = temp;
+			timestamp = file.lastModified();
+		}
+		fileListenerThread.start();
+	}
+	
+	protected static File getFile(String location) {
+		if (location == null)
+			return null;
+		if (location.startsWith("file:/")) //$NON-NLS-1$
+			location = location.substring(6);
+		
+		return new File(location);
+	}
+	
+	protected void removeSynchronizationListener() {
+		if (fileListenerThread == null)
+			return;
+		
+		fileListenerThread = null;
+		browser.removeLocationListener(locationListener2);
+		locationListener2 = null;
+	}
+}

Property changes on: tmp/org.txm.libs.javafx/swt/JFXBrowserViewer.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.libs.javafx/swt/JFXBrowserText.java
===================================================================
--- tmp/org.txm.libs.javafx/swt/JFXBrowserText.java	(revision 0)
+++ tmp/org.txm.libs.javafx/swt/JFXBrowserText.java	(revision 3108)
@@ -0,0 +1,182 @@
+package snippet;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Link;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.internal.browser.FallbackScrolledComposite;
+import org.eclipse.ui.internal.browser.IBrowserViewerContainer;
+
+public class JFXBrowserText {
+	
+	private String url;
+	
+	private FallbackScrolledComposite scomp;
+	
+	private Label title;
+	
+	private Label exTitle;
+	
+	private Label text;
+	
+	private Label sep;
+	
+	protected Link link;
+	
+	private JFXBrowserViewer viewer;
+	
+	private Button button;
+	
+	private Text exception;
+	
+	private boolean expanded;
+	
+	private Throwable ex;
+	
+	class ReflowScrolledComposite extends FallbackScrolledComposite {
+		
+		public ReflowScrolledComposite(Composite parent, int style) {
+			super(parent, style);
+		}
+		
+		@Override
+		public void reflow(boolean flushCache) {
+			updateWidth(this);
+			super.reflow(flushCache);
+		}
+	}
+	
+	public JFXBrowserText(Composite parent, JFXBrowserViewer viewer, Throwable ex) {
+		this.viewer = viewer;
+		this.ex = ex;
+		Color bg = parent.getDisplay()
+				.getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+		scomp = new ReflowScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
+		Composite client = new Composite(scomp, SWT.NULL);
+		fillContent(client, bg);
+		scomp.setContent(client);
+		scomp.setBackground(bg);
+	}
+	
+	private void fillContent(Composite parent, Color bg) {
+		GridLayout layout = new GridLayout();
+		layout.verticalSpacing = 10;
+		parent.setLayout(layout);
+		title = new Label(parent, SWT.WRAP);
+		title.setText(org.eclipse.ui.internal.browser.Messages.BrowserText_title);
+		title.setFont(JFaceResources.getHeaderFont());
+		title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		title.setBackground(bg);
+		
+		link = new Link(parent, SWT.WRAP);
+		link.setText(org.eclipse.ui.internal.browser.Messages.BrowserText_link);
+		link.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		link.setToolTipText(org.eclipse.ui.internal.browser.Messages.BrowserText_tooltip);
+		link.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
+			BusyIndicator.showWhile(link.getDisplay(), () -> doOpenExternal());
+		}));
+		link.setBackground(bg);
+		sep = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
+		sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		exTitle = new Label(parent, SWT.NULL);
+		exTitle.setBackground(bg);
+		exTitle.setFont(JFaceResources.getBannerFont());
+		exTitle.setText(org.eclipse.ui.internal.browser.Messages.BrowserText_dtitle);
+		exTitle.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		text = new Label(parent, SWT.WRAP);
+		text.setText(org.eclipse.ui.internal.browser.Messages.BrowserText_text);
+		text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+		text.setBackground(bg);
+		button = new Button(parent, SWT.PUSH);
+		updateButtonText();
+		button.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> {
+			toggleException();
+		}));
+		exception = new Text(parent, SWT.MULTI);
+		loadExceptionText();
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		gd.exclude = true;
+		exception.setLayoutData(gd);
+	}
+	
+	private void loadExceptionText() {
+		StringWriter swriter = new StringWriter();
+		try (PrintWriter writer = new PrintWriter(swriter)) {
+			writer.println(ex.getMessage());
+			ex.printStackTrace(writer);
+		}
+		exception.setText(swriter.toString());
+	}
+	
+	protected void toggleException() {
+		expanded = !expanded;
+		updateButtonText();
+		GridData gd = (GridData) exception.getLayoutData();
+		gd.exclude = !expanded;
+		exception.setVisible(expanded);
+		refresh();
+	}
+	
+	private void updateButtonText() {
+		if (expanded)
+			button.setText(org.eclipse.ui.internal.browser.Messages.BrowserText_button_collapse);
+		else
+			button.setText(org.eclipse.ui.internal.browser.Messages.BrowserText_button_expand);
+	}
+	
+	protected void updateWidth(Composite parent) {
+		Rectangle area = parent.getClientArea();
+		updateWidth(title, area.width);
+		updateWidth(text, area.width);
+		updateWidth(sep, area.width);
+		updateWidth(link, area.width);
+		updateWidth(exTitle, area.width);
+		updateWidth(exception, area.width);
+	}
+	
+	private void updateWidth(Control c, int width) {
+		GridData gd = (GridData) c.getLayoutData();
+		if (gd != null)
+			gd.widthHint = width - 10;
+	}
+	
+	protected void doOpenExternal() {
+		IBrowserViewerContainer container = viewer.getContainer();
+		if (container != null)
+			container.openInExternalBrowser(url);
+	}
+	
+	public Control getControl() {
+		return scomp;
+	}
+	
+	public boolean setUrl(String url) {
+		this.url = url;
+		return true;
+	}
+	
+	public void setFocus() {
+		link.setFocus();
+	}
+	
+	public String getUrl() {
+		return url;
+	}
+	
+	public void refresh() {
+		scomp.reflow(true);
+	}
+}

Property changes on: tmp/org.txm.libs.javafx/swt/JFXBrowserText.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.libs.javafx/swt/JFXBrowser.java
===================================================================
--- tmp/org.txm.libs.javafx/swt/JFXBrowser.java	(revision 0)
+++ tmp/org.txm.libs.javafx/swt/JFXBrowser.java	(revision 3108)
@@ -0,0 +1,388 @@
+package snippet;
+
+import java.util.concurrent.Semaphore;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.SWTError;
+import org.eclipse.swt.browser.CloseWindowListener;
+import org.eclipse.swt.browser.LocationEvent;
+import org.eclipse.swt.browser.LocationListener;
+import org.eclipse.swt.browser.OpenWindowListener;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.browser.StatusTextListener;
+import org.eclipse.swt.browser.TitleListener;
+import org.eclipse.swt.browser.VisibilityWindowAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.ProgressBar;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.ToolBar;
+import org.eclipse.swt.widgets.ToolItem;
+
+import javafx.application.Platform;
+import javafx.embed.swt.FXCanvas;
+import javafx.scene.Group;
+import javafx.scene.Scene;
+import javafx.scene.paint.Color;
+import javafx.scene.web.WebView;
+
+/**
+ * WebView (webkit) wrapper.
+ * not finished, see work to be done in org.eclipse.swt.browser.Webkit.class to make this class fully operational
+ * 
+ * @author mdecorde
+ *
+ */
+public class JFXBrowser extends FXCanvas {
+	
+	protected static final String NOMEDIA = ""; //$NON-NLS-1$
+	
+	private WebView jfxBrowser;
+	
+	// private GLComposite videoComposite;
+	
+	public WebView getEmbeddedMediaPlayer() {
+		return jfxBrowser;
+	}
+	
+	Semaphore s = new Semaphore(1);
+	
+	// private FXCanvas fxCanvas;
+	
+	Point previousP;
+	
+	public JFXBrowser(Composite parent, int style) {
+		super(parent, style);
+		GridLayout gl = new GridLayout(1, true);
+		gl.horizontalSpacing = 0;
+		this.setLayout(gl);
+		
+		// THE PLAYER
+		// if (RuntimeUtil.isMac()) {
+		// try {
+		// LibC.INSTANCE.setenv("VLC_PLUGIN_PATH", "/Applications/VLC.app/Contents/MacOS/plugins", 1);
+		// }
+		// catch (Exception ex) {
+		// ex.printStackTrace();
+		// }
+		// }
+		// videoComposite = new GLComposite(this, SWT.NONE, "Video");
+		GridData gdata = new GridData(SWT.FILL, SWT.FILL, true, true);
+		this.setLayoutData(gdata);
+		jfxBrowser = null;
+		
+		this.addListener(SWT.Resize, new Listener() {
+			
+			@Override
+			public void handleEvent(Event e) {
+				resizeView();
+			}
+		});
+		
+		// fxCanvas = new FXCanvas(videoComposite, SWT.BORDER);
+		// GridData gdata2 = new GridData(SWT.FILL, SWT.FILL, true, true);
+		// fxCanvas.setLayoutData(gdata2);
+		
+		initializeBrowser();
+	}
+	
+	// @Override
+	// public void addMouseListener(MouseListener listener) {
+	// // jfxBrowser.setOnMousePressed(new EventHandler<MouseEvent>() {
+	// //
+	// // @Override
+	// // public void handle(MouseEvent event) {
+	// // // TODO Auto-generated method stub
+	// //
+	// // }
+	// // });
+	// fxCanvas.addMouseListener(listener);
+	// }
+	
+	protected void resizeView() {
+		if (jfxBrowser != null) {
+			Point p = this.getSize();
+			// if (previousP == null || (p.x != previousP.x && p.y != previousP.y)) { // ensure size changed
+			jfxBrowser.setPrefHeight(p.y);
+			// jfxBrowser.setMaxWidth(p.x);
+			jfxBrowser.setPrefWidth(p.x);
+			previousP = p;
+			// }
+		}
+	}
+	
+	private Group group;
+	
+	private Scene scene;
+	
+	protected boolean initializeBrowser() {
+		
+		Platform.setImplicitExit(false);
+		jfxBrowser = new WebView();
+		
+		group = new Group(jfxBrowser);
+		
+		// scene = new Scene(group, Color.rgb(fxCanvas.getBackground().getRed(), fxCanvas.getBackground().getGreen(), fxCanvas.getBackground().getBlue()));
+		scene = new Scene(group, Color.rgb(0, 0, 0));
+		
+		this.setScene(jfxBrowser.getScene());
+		
+		return true;
+	}
+	
+	public boolean back() {
+		try {
+			jfxBrowser.getEngine().getHistory().go(-1);
+			return true;
+		}
+		catch (Exception e) {
+			return false;
+		}
+	}
+	
+	public boolean forward() {
+		try {
+			jfxBrowser.getEngine().getHistory().go(1);
+			return true;
+		}
+		catch (Exception e) {
+			return false;
+		}
+	}
+	
+	public void stop() {
+		// jfxBrowser.getEngine().canc();
+		System.out.println("TODO JFXBrowser.stop...");
+	}
+	
+	public void refresh() {
+		jfxBrowser.getEngine().reload();
+	}
+	
+	public void setUrl(String url) {
+		jfxBrowser.getEngine().load(url);
+	}
+	
+	public void addProgressListener(ProgressListener progressListener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addProgressListener(" + progressListener + ")");
+	}
+	
+	public void addStatusTextListener(StatusTextListener listener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addStatusTextListener(" + listener + ")");
+	}
+	
+	public void addLocationListener(LocationListener locationListener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addLocationListener(" + locationListener + ")");
+	}
+	
+	public void addOpenWindowListener(OpenWindowListener listener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addOpenWindowListener(" + listener + ")");
+	}
+	
+	public void addVisibilityWindowListener(VisibilityWindowAdapter visibilityWindowAdapter) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addVisibilityWindowListener(" + visibilityWindowAdapter + ")");
+	}
+	
+	public void addCloseWindowListener(CloseWindowListener listener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addCloseWindowListener(" + listener + ")");
+	}
+	
+	public void addTitleListener(TitleListener listener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.addTitleListener(" + listener + ")");
+	}
+	
+	public void removeLocationListener(LocationListener locationListener) {
+		// TODO Auto-generated method stub
+		System.out.println("TODO JFXBrowser.removeLocationListener(" + locationListener + ")");
+	}
+	
+	public static void main(String[] args) {
+		Display display = new Display();
+		final Shell shell = new Shell(display);
+		shell.setText("Snippet 128");
+		GridLayout gridLayout = new GridLayout();
+		gridLayout.numColumns = 3;
+		shell.setLayout(gridLayout);
+		ToolBar toolbar = new ToolBar(shell, SWT.NONE);
+		ToolItem itemBack = new ToolItem(toolbar, SWT.PUSH);
+		itemBack.setText("Back");
+		ToolItem itemForward = new ToolItem(toolbar, SWT.PUSH);
+		itemForward.setText("Forward");
+		ToolItem itemStop = new ToolItem(toolbar, SWT.PUSH);
+		itemStop.setText("Stop");
+		ToolItem itemRefresh = new ToolItem(toolbar, SWT.PUSH);
+		itemRefresh.setText("Refresh");
+		ToolItem itemGo = new ToolItem(toolbar, SWT.PUSH);
+		itemGo.setText("Go");
+		
+		GridData data = new GridData();
+		data.horizontalSpan = 3;
+		toolbar.setLayoutData(data);
+		
+		Label labelAddress = new Label(shell, SWT.NONE);
+		labelAddress.setText("Address");
+		
+		final Text location = new Text(shell, SWT.BORDER);
+		data = new GridData();
+		data.horizontalAlignment = GridData.FILL;
+		data.horizontalSpan = 2;
+		data.grabExcessHorizontalSpace = true;
+		location.setLayoutData(data);
+		
+		final JFXBrowser browser;
+		try {
+			browser = new JFXBrowser(shell, SWT.NONE);
+		}
+		catch (SWTError e) {
+			System.out.println("Could not instantiate Browser: " + e.getMessage());
+			display.dispose();
+			return;
+		}
+		data = new GridData();
+		data.horizontalAlignment = GridData.FILL;
+		data.verticalAlignment = GridData.FILL;
+		data.horizontalSpan = 3;
+		data.grabExcessHorizontalSpace = true;
+		data.grabExcessVerticalSpace = true;
+		browser.setLayoutData(data);
+		
+		final Label status = new Label(shell, SWT.NONE);
+		data = new GridData(GridData.FILL_HORIZONTAL);
+		data.horizontalSpan = 2;
+		status.setLayoutData(data);
+		
+		final ProgressBar progressBar = new ProgressBar(shell, SWT.NONE);
+		data = new GridData();
+		data.horizontalAlignment = GridData.END;
+		progressBar.setLayoutData(data);
+		
+		/* event handling */
+		Listener listener = event -> {
+			ToolItem item = (ToolItem) event.widget;
+			String string = item.getText();
+			if (string.equals("Back"))
+				browser.back();
+			else if (string.equals("Forward"))
+				browser.forward();
+			else if (string.equals("Stop"))
+				browser.stop();
+			else if (string.equals("Refresh"))
+				browser.refresh();
+			else if (string.equals("Go"))
+				browser.setUrl(location.getText());
+		};
+		browser.addProgressListener(new ProgressListener() {
+			
+			@Override
+			public void changed(ProgressEvent event) {
+				if (event.total == 0) return;
+				int ratio = event.current * 100 / event.total;
+				progressBar.setSelection(ratio);
+			}
+			
+			@Override
+			public void completed(ProgressEvent event) {
+				progressBar.setSelection(0);
+			}
+		});
+		
+		browser.addLocationListener(new LocationListener() {
+			
+			@Override
+			public void changing(LocationEvent event) {}
+			
+			@Override
+			public void changed(LocationEvent event) {
+				if (event.top) location.setText(event.location);
+			}
+		});
+		// browser.addLocationListener(LocationListener.changed(event -> {
+		// if (event.top) location.setText(event.location);
+		// }));
+		itemBack.addListener(SWT.Selection, listener);
+		itemForward.addListener(SWT.Selection, listener);
+		itemStop.addListener(SWT.Selection, listener);
+		itemRefresh.addListener(SWT.Selection, listener);
+		itemGo.addListener(SWT.Selection, listener);
+		location.addListener(SWT.DefaultSelection, e -> browser.setUrl(location.getText()));
+		
+		browser.addMouseListener(new MouseListener() {
+			
+			@Override
+			public void mouseUp(MouseEvent e) {
+				System.out.println("M UP");
+			}
+			
+			@Override
+			public void mouseDown(MouseEvent e) {
+				System.out.println("M DOWN");
+			}
+			
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {
+				System.out.println("M DCLICK");
+			}
+		});
+		
+		browser.addKeyListener(new KeyListener() {
+			
+			@Override
+			public void keyReleased(KeyEvent e) {}
+			
+			@Override
+			public void keyPressed(KeyEvent e) {
+				System.out.println("K " + e);
+			}
+		});
+		
+		shell.open();
+		// browser.setUrl("http://eclipse.org");
+		
+		while (!shell.isDisposed()) {
+			if (!display.readAndDispatch())
+				display.sleep();
+		}
+		display.dispose();
+	}
+	
+	public WebView getWebView() {
+		return this.jfxBrowser;
+	}
+	
+	public String getUrl() {
+		return jfxBrowser.getEngine().getLocation();
+	}
+	
+	public boolean isBackEnabled() {
+		return jfxBrowser.getEngine().getHistory().getCurrentIndex() > 0;
+	}
+	
+	public boolean isForwardEnabled() {
+		return jfxBrowser.getEngine().getHistory().getCurrentIndex() < jfxBrowser.getEngine().getHistory().getEntries().size();
+	}
+	
+	public boolean setUrl(String url, String postData, String[] headers) {
+		// TODO Auto-generated method stub
+		jfxBrowser.getEngine().load(url);
+		return true;
+	}
+}

Property changes on: tmp/org.txm.libs.javafx/swt/JFXBrowser.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Index: tmp/org.txm.libs.javafx/swt/TXMJFXBrowserEditor.java
===================================================================
--- tmp/org.txm.libs.javafx/swt/TXMJFXBrowserEditor.java	(revision 0)
+++ tmp/org.txm.libs.javafx/swt/TXMJFXBrowserEditor.java	(revision 3108)
@@ -0,0 +1,392 @@
+/*******************************************************************************
+ * Copyright (c) 2003, 2016 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are 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:
+ *     IBM Corporation - Initial API and implementation
+ *     
+ *     
+ *******************************************************************************/
+package snippet;
+
+import java.beans.PropertyChangeListener;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.eclipse.core.runtime.Adapters;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorReference;
+import org.eclipse.ui.IEditorRegistry;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IPathEditorInput;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
+import org.eclipse.ui.internal.browser.BrowserViewer;
+import org.eclipse.ui.internal.browser.IBrowserViewerContainer;
+import org.eclipse.ui.internal.browser.ImageResource;
+import org.eclipse.ui.internal.browser.TextAction;
+import org.eclipse.ui.internal.browser.Trace;
+import org.eclipse.ui.internal.browser.WebBrowserEditorInput;
+import org.eclipse.ui.internal.browser.WebBrowserUIPlugin;
+import org.eclipse.ui.part.EditorPart;
+
+/**
+ * An integrated JFX Web browser (webkit), defined as an editor to make better use of the desktop.
+ * 
+ * TODO the JFXBrowser has to implements lots of event trigger to be fully functionnal
+ */
+public class TXMJFXBrowserEditor extends EditorPart implements IBrowserViewerContainer {
+	
+	protected static final String PROPERTY_TITLE = "title"; //$NON-NLS-1$
+	
+	public static final String WEB_BROWSER_EDITOR_ID = "org.txm.rcp.editors.TXMJFXBrowserEditor"; //$NON-NLS-1$
+	
+	protected JFXBrowserViewer webBrowser;
+	
+	protected String initialURL;
+	
+	protected Image image;
+	
+	protected TextAction cutAction;
+	
+	protected TextAction copyAction;
+	
+	protected TextAction pasteAction;
+	
+	private boolean disposed;
+	
+	private boolean lockName;
+	
+	/**
+	 * WebBrowserEditor constructor comment.
+	 */
+	public TXMJFXBrowserEditor() {
+		super();
+	}
+	
+	@Override
+	public void createPartControl(Composite parent) {
+		WebBrowserEditorInput input = getWebBrowserEditorInput();
+		
+		int style = 0;
+		if (input == null || input.isLocationBarLocal()) {
+			style += BrowserViewer.LOCATION_BAR;
+		}
+		if (input == null || input.isToolbarLocal()) {
+			style += BrowserViewer.BUTTON_BAR;
+		}
+		webBrowser = new JFXBrowserViewer(parent, style);
+		
+		webBrowser.setURL(initialURL);
+		webBrowser.setContainer(this);
+		
+		if (input == null || input.isLocationBarLocal()) {
+			// cutAction = new TextAction(webBrowser, TextAction.CUT);
+			// copyAction = new TextAction(webBrowser, TextAction.COPY);
+			// pasteAction = new TextAction(webBrowser, TextAction.PASTE);
+		}
+		
+		if (!lockName) {
+			PropertyChangeListener propertyChangeListener = event -> {
+				if (PROPERTY_TITLE.equals(event.getPropertyName())) {
+					setPartName((String) event.getNewValue());
+				}
+			};
+			webBrowser.addPropertyChangeListener(propertyChangeListener);
+		}
+	}
+	
+	@Override
+	public void setPartName(String partName) {
+		super.setPartName(partName);
+	}
+	
+	@Override
+	public void setTitleImage(Image titleImage) {
+		super.setTitleImage(titleImage);
+	}
+	
+	@Override
+	public void dispose() {
+		if (image != null && !image.isDisposed())
+			image.dispose();
+		image = null;
+		
+		super.dispose();
+		// mark this instance as disposed to avoid stale references
+		disposed = true;
+	}
+	
+	public boolean isDisposed() {
+		return disposed;
+	}
+	
+	@Override
+	public void doSave(IProgressMonitor monitor) {
+		// do nothing
+	}
+	
+	@Override
+	public void doSaveAs() {
+		// do nothing
+	}
+	
+	/**
+	 * Returns the copy action.
+	 *
+	 * @return org.eclipse.jface.action.IAction
+	 */
+	public IAction getCopyAction() {
+		return copyAction;
+	}
+	
+	/**
+	 * Returns the cut action.
+	 *
+	 * @return org.eclipse.jface.action.IAction
+	 */
+	public IAction getCutAction() {
+		return cutAction;
+	}
+	
+	/**
+	 * Returns the web editor input, if available. If the input was of
+	 * another type, <code>null</code> is returned.
+	 *
+	 * @return org.eclipse.ui.internal.browser.IWebBrowserEditorInput
+	 */
+	protected WebBrowserEditorInput getWebBrowserEditorInput() {
+		IEditorInput input = getEditorInput();
+		if (input instanceof WebBrowserEditorInput)
+			return (WebBrowserEditorInput) input;
+		return null;
+	}
+	
+	/**
+	 * Returns the paste action.
+	 *
+	 * @return org.eclipse.jface.action.IAction
+	 */
+	public IAction getPasteAction() {
+		return pasteAction;
+	}
+	
+	@Override
+	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
+		Trace.trace(Trace.FINEST, "Opening browser: " + input); //$NON-NLS-1$
+		if (input instanceof IPathEditorInput) {
+			IPathEditorInput pei = (IPathEditorInput) input;
+			final IPath path = pei.getPath();
+			URL url = null;
+			try {
+				if (path != null) {
+					setPartName(path.lastSegment());
+					url = path.toFile().toURI().toURL();
+				}
+				if (url != null)
+					initialURL = url.toExternalForm();
+			}
+			catch (Exception e) {
+				Trace.trace(Trace.SEVERE, "Error getting URL to file"); //$NON-NLS-1$
+			}
+			if (webBrowser != null) {
+				if (initialURL != null)
+					webBrowser.setURL(initialURL);
+				site.getWorkbenchWindow().getActivePage().activate(this);
+			}
+			
+			if (url != null)
+				setTitleToolTip(url.getFile());
+			
+			Image oldImage = image;
+			ImageDescriptor id = ImageResource.getImageDescriptor(ImageResource.IMG_INTERNAL_BROWSER);
+			image = id.createImage();
+			
+			setTitleImage(image);
+			if (oldImage != null && !oldImage.isDisposed())
+				oldImage.dispose();
+			// addResourceListener(file);
+		}
+		else if (input instanceof WebBrowserEditorInput) {
+			WebBrowserEditorInput wbei = (WebBrowserEditorInput) input;
+			initialURL = null;
+			if (wbei.getURL() != null)
+				initialURL = wbei.getURL().toExternalForm();
+			if (webBrowser != null) {
+				webBrowser.setURL(initialURL);
+				site.getWorkbenchWindow().getActivePage().activate(this);
+			}
+			
+			setPartName(wbei.getName());
+			setTitleToolTip(wbei.getToolTipText());
+			lockName = false;
+			
+			Image oldImage = image;
+			ImageDescriptor id = wbei.getImageDescriptor();
+			image = id.createImage();
+			
+			setTitleImage(image);
+			if (oldImage != null && !oldImage.isDisposed())
+				oldImage.dispose();
+		}
+		else {
+			IPathEditorInput pinput = Adapters.adapt(input, IPathEditorInput.class);
+			if (pinput != null) {
+				init(site, pinput);
+			}
+			else {
+				throw new PartInitException(NLS.bind(org.eclipse.ui.internal.browser.Messages.errorInvalidEditorInput, input.getName()));
+			}
+		}
+		
+		setSite(site);
+		setInput(input);
+	}
+	
+	@Override
+	public boolean isDirty() {
+		return false;
+	}
+	
+	@Override
+	public boolean isSaveAsAllowed() {
+		return false;
+	}
+	
+	/**
+	 * Open the input in the internal Web browser.
+	 */
+	public static void open(WebBrowserEditorInput input) {
+		IWorkbenchWindow workbenchWindow = WebBrowserUIPlugin.getInstance().getWorkbench().getActiveWorkbenchWindow();
+		IWorkbenchPage page = workbenchWindow.getActivePage();
+		
+		try {
+			IEditorReference[] editors = page.getEditorReferences();
+			int size = editors.length;
+			for (int i = 0; i < size; i++) {
+				if (WEB_BROWSER_EDITOR_ID.equals(editors[i].getId())) {
+					IEditorPart editor = editors[i].getEditor(true);
+					if (editor != null && editor instanceof TXMJFXBrowserEditor) {
+						TXMJFXBrowserEditor webEditor = (TXMJFXBrowserEditor) editor;
+						WebBrowserEditorInput input2 = webEditor.getWebBrowserEditorInput();
+						if (input2 == null || input.canReplaceInput(input2)) {
+							editor.init(editor.getEditorSite(), input);
+							return;
+						}
+					}
+				}
+			}
+			
+			page.openEditor(input, TXMJFXBrowserEditor.WEB_BROWSER_EDITOR_ID);
+		}
+		catch (Exception e) {
+			Trace.trace(Trace.SEVERE, "Error opening Web browser", e); //$NON-NLS-1$
+		}
+	}
+	
+	/*
+	 * Asks this part to take focus within the workbench.
+	 */
+	@Override
+	public void setFocus() {
+		if (webBrowser != null)
+			webBrowser.setFocus();
+	}
+	
+	/**
+	 * Close the editor correctly.
+	 */
+	@Override
+	public boolean close() {
+		final boolean[] result = new boolean[1];
+		Display.getDefault()
+				.asyncExec(() -> result[0] = getEditorSite().getPage().closeEditor(TXMJFXBrowserEditor.this, false));
+		return result[0];
+	}
+	
+	@Override
+	public IActionBars getActionBars() {
+		return getEditorSite().getActionBars();
+	}
+	
+	@Override
+	public void openInExternalBrowser(String url) {
+		final IEditorInput input = getEditorInput();
+		final String id = getEditorSite().getId();
+		Runnable runnable = () -> doOpenExternalEditor(id, input);
+		Display display = getSite().getShell().getDisplay();
+		close();
+		display.asyncExec(runnable);
+	}
+	
+	protected void doOpenExternalEditor(String id, IEditorInput input) {
+		IEditorRegistry registry = PlatformUI.getWorkbench().getEditorRegistry();
+		String name = input.getName();
+		IEditorDescriptor[] editors = registry.getEditors(name);
+		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+		
+		String editorId = null;
+		for (IEditorDescriptor editor : editors) {
+			if (editor.getId().equals(id))
+				continue;
+			editorId = editor.getId();
+			break;
+		}
+		
+		IEditorDescriptor ddesc = registry.getDefaultEditor(name);
+		if (ddesc != null && ddesc.getId().equals(id)) {
+			int dot = name.lastIndexOf('.');
+			String ext = name;
+			if (dot != -1)
+				ext = "*." + name.substring(dot + 1); //$NON-NLS-1$
+			registry.setDefaultEditor(ext, null);
+		}
+		
+		if (editorId == null) {
+			// no editor
+			// next check with the OS for an external editor
+			if (registry.isSystemExternalEditorAvailable(name))
+				editorId = IEditorRegistry.SYSTEM_EXTERNAL_EDITOR_ID;
+		}
+		
+		if (editorId != null) {
+			try {
+				page.openEditor(input, editorId);
+				return;
+			}
+			catch (PartInitException e) {
+				// ignore
+			}
+		}
+		
+		// no registered editor - open using browser support
+		try {
+			URL theURL = new URL(webBrowser.getURL());
+			IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
+			support.getExternalBrowser().openURL(theURL);
+		}
+		catch (MalformedURLException e) {
+			// TODO handle this
+		}
+		catch (PartInitException e) {
+			// TODO handle this
+		}
+	}
+}

Property changes on: tmp/org.txm.libs.javafx/swt/TXMJFXBrowserEditor.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

