/*********************************************************************** * Copyright (c) 2008 Anyware Technologies * * 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: * Gilles Cannenterre (Anyware Technologies) - initial API and implementation **********************************************************************/ package org.eclipse.papyrus.views.documentation.view; import java.net.MalformedURLException; import java.net.URL; import org.eclipse.emf.common.util.URI; import org.eclipse.swt.SWT; import org.eclipse.swt.browser.Browser; import org.eclipse.swt.browser.LocationAdapter; import org.eclipse.swt.browser.LocationEvent; import org.eclipse.swt.custom.BusyIndicator; 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.ui.IEditorPart; import org.eclipse.epf.richtext.RichText; /** * A class defining a composite support rich text edition.<br> * creation : 12 juin 2008 * * @author <a href="mailto:gilles.cannenterre@anyware-tech.com">Gilles Cannenterre</a> */ public class RichTextComposite extends Composite { private RichText commentsText; /** * Constructor. * * @param parent the parent composite * @param style the composite style */ public RichTextComposite(Composite parent, int style) { super(parent, style); Composite container = new Composite(this, SWT.BORDER); GridLayout richTextLayout = new GridLayout(); richTextLayout.marginWidth = 0; richTextLayout.marginHeight = 0; container.setLayout(richTextLayout); container.setLayoutData(new GridData(GridData.FILL_BOTH)); commentsText = new RichText(container, SWT.NONE); commentsText.setEditable(false); commentsText.setLayoutData(new GridData(GridData.FILL_BOTH)); // the Rich Text control is a Browser for sure. Browser browser = (Browser) commentsText.getControl(); browser.addLocationListener(new URLLocationListener()); } /** * This method returns the text contained in the <code>RichTextCommentsComposite</code> * * @return the text contained in the <code>RichTextCommentsComposite</code> */ public String getDocumentationValue() { return commentsText.getText(); } /** * Sets the given text into the <code>RichTextCommentsComposite</code> * * @param text text to put into the <code>RichTextCommentsComposite</code> */ public void setDocumentationValue(String text) { commentsText.setText(text); } /** * A Location Listener that knows how to intercept OOBE action URLs. It also * knows how to update UI navigation history. */ private static class URLLocationListener extends LocationAdapter { @Override public void changing(LocationEvent event) { String url = event.location; if (url == null) return; URLParser parser = new URLParser(url); if (parser.isValidURI()) { // stop URL first. event.doit = false; // execute the action embedded in the IntroURL parser.runURL(); } } } /** * A parser that knows how to parser OOBE action URLs. If URL is a valid url, * it will create an instance of the IntroURL class. */ private static class URLParser { private static final String HTTP_PROTOCOL = "http"; //$NON-NLS-1$ private static final String PLATFORM_PROTOCOL = "platform"; //$NON-NLS-1$ private URI uri; /** * Constructor that create a URL instance, to validate the URL and create a correct URI. */ private URLParser(String url) { parseUrl(url); } private void parseUrl(String url) { if (url == null) return; this.uri = null; try { // TODO check parsing url // URL has some valid protocol. // Check to see if it is a valid url. URL url_inst = new URL(url); String protocol2 = url_inst.getProtocol(); if (protocol2 != null) { // XXX : HACK Extreme hacking on... // there should be a proper way to handle with spaces and URIs. if (protocol2.equalsIgnoreCase(HTTP_PROTOCOL)) { this.uri = URI.createURI(URI.decode(url.replace("http://platform", "platform:").replace("platform::/", "platform:/")));//.replaceAll("%20", " ")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ } else if (protocol2.equalsIgnoreCase(PLATFORM_PROTOCOL)) { this.uri = URI.createURI(URI.decode(url)); } } } catch (MalformedURLException e) { // not a valid URL. Just return. } } /** * @return Returns the isIntroUrl. */ private boolean isValidURI() { return uri != null; } /** * Fin the EObject with the given URL and try select it on the current Modeler. */ private void runURL() { Display display = Display.getCurrent(); BusyIndicator.showWhile(display, new Runnable() { public void run() { IEditorPart activeEditor = DocViewPlugin.getActiveEditor(); IDocumentationPartHandler documentationEditor = DocumentionPartHandlerRegistry.getInstance().getDocumentationPartHandler(activeEditor); if (documentationEditor != null) { documentationEditor.openElement(activeEditor, uri); } } }); } } @Override public void setEnabled(boolean enabled) { if (!isDisposed()) { super.setEnabled(enabled); if (commentsText != null && commentsText.getControl() != null) { commentsText.getControl().setEnabled(enabled); } } } }