/******************************************************************************* * Copyright (c) 2004, 2012 Tasktop Technologies 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: * Tasktop Technologies - initial API and implementation * Xiaoyang Guan - browser preview *******************************************************************************/ package org.eclipse.mylyn.internal.tasks.ui.editors; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.mylyn.commons.workbench.browser.BrowserUtil; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal; import org.eclipse.mylyn.tasks.core.RepositoryStatus; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.ui.editors.AbstractRenderingEngine; 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.widgets.Composite; import org.eclipse.ui.forms.widgets.FormToolkit; /** * @author Steffen Pingel * @author Xiaoyang Guan */ public class BrowserPreviewViewer { private Browser browser; private boolean ignoreLocationEvents; private final AbstractRenderingEngine renderingEngine; private final TaskRepository taskRepository; public BrowserPreviewViewer(TaskRepository taskRepository, AbstractRenderingEngine renderingEngine) { Assert.isNotNull(taskRepository); Assert.isNotNull(renderingEngine); this.taskRepository = taskRepository; this.renderingEngine = renderingEngine; } public void createControl(Composite parent, FormToolkit toolkit) { browser = new Browser(parent, SWT.NONE); // intercept links to open tasks in rich editor and urls in separate browser browser.addLocationListener(new LocationAdapter() { @Override public void changing(LocationEvent event) { // ignore events that are caused by manually setting the contents of the browser if (ignoreLocationEvents) { return; } if (event.location != null && !event.location.startsWith("about")) { //$NON-NLS-1$ event.doit = false; BrowserUtil.openUrl(event.location); } } }); } public Browser getControl() { return browser; } private void previewWiki(final Browser browser, String sourceText) { final class PreviewWikiJob extends Job { private String htmlText; private IStatus jobStatus; private final String sourceText; public PreviewWikiJob(String sourceText) { super(Messages.BrowserPreviewViewer_Formatting_Wiki_Text); if (sourceText == null) { throw new IllegalArgumentException("source text must not be null"); //$NON-NLS-1$ } this.sourceText = sourceText; } public String getHtmlText() { return htmlText; } public IStatus getStatus() { return jobStatus; } @Override protected IStatus run(IProgressMonitor monitor) { if (renderingEngine == null) { jobStatus = new RepositoryStatus(taskRepository, IStatus.INFO, TasksUiPlugin.ID_PLUGIN, RepositoryStatus.ERROR_INTERNAL, Messages.BrowserPreviewViewer_The_repository_does_not_support_HTML_preview); return Status.OK_STATUS; } jobStatus = Status.OK_STATUS; try { htmlText = renderingEngine.renderAsHtml(taskRepository, sourceText, monitor); } catch (CoreException e) { jobStatus = e.getStatus(); } return Status.OK_STATUS; } } final PreviewWikiJob job = new PreviewWikiJob(sourceText); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(final IJobChangeEvent event) { if (!browser.isDisposed()) { if (job.getStatus().isOK()) { browser.getDisplay().asyncExec(new Runnable() { public void run() { setText(browser, job.getHtmlText()); // TODO 3.5 error handling //getAttributeEditorManager().setMessage(null, IMessageProvider.NONE); } }); } else { browser.getDisplay().asyncExec(new Runnable() { public void run() { TasksUiInternal.displayStatus(Messages.BrowserPreviewViewer_Error, job.getStatus()); // TODO 3.5 error handling //getAttributeEditorManager().setMessage(job.getStatus().getMessage(), IMessageProvider.ERROR); } }); } } super.done(event); } }); job.setUser(true); job.schedule(); } private void setText(Browser browser, String html) { try { ignoreLocationEvents = true; browser.setText((html != null) ? html : ""); //$NON-NLS-1$ } finally { ignoreLocationEvents = false; } } public void update(String value) { setText(browser, Messages.BrowserPreviewViewer_Loading_preview_); previewWiki(browser, value); } }