/*
* Copyright 2015 Nokia Solutions and Networks
* Licensed under the Apache License, Version 2.0,
* see license.txt file for details.
*/
package org.robotframework.ide.eclipse.main.plugin.navigator.actions;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.ScrolledFormText;
import org.robotframework.ide.eclipse.main.plugin.RedImages;
import org.robotframework.ide.eclipse.main.plugin.project.library.KeywordSpecification;
import org.robotframework.red.jface.dialogs.InputLoadingFormComposite;
class KeywordDocumentationComposite extends InputLoadingFormComposite {
private InputLoadingFormComposite.InputJob collectingJob;
private FormText argumentsText;
private ScrolledFormText scrolledFormText;
private FormText documentationText;
KeywordDocumentationComposite(final Composite parent, final KeywordSpecification specification) {
super(parent, SWT.NONE, specification.getName());
this.collectingJob = new InputLoadingFormComposite.InputJob("Loading keyword documentation") {
@Override
protected Object createInput(final IProgressMonitor monitor) {
setStatus(Status.OK_STATUS);
return new Documentation(specification);
}
};
createComposite();
}
@Override
protected Composite createControl(final Composite parent) {
setFormImage(RedImages.getKeywordImage());
final Composite actualComposite = getToolkit().createComposite(parent);
GridLayoutFactory.fillDefaults().numColumns(2).margins(3, 3).applyTo(actualComposite);
argumentsText = getToolkit().createFormText(actualComposite, false);
argumentsText.setFont("monospace", JFaceResources.getTextFont());
argumentsText.setFont("monospace_inline", JFaceResources.getTextFont());
argumentsText.setColor("header", getToolkit().getColors().getColor(IFormColors.TITLE));
argumentsText.setFont("header", JFaceResources.getBannerFont());
GridDataFactory.fillDefaults().span(2, 1).hint(400, SWT.DEFAULT).grab(true, false).applyTo(argumentsText);
scrolledFormText = new ScrolledFormText(actualComposite, SWT.V_SCROLL | SWT.H_SCROLL, true);
getToolkit().adapt(scrolledFormText);
GridDataFactory.fillDefaults().span(2, 1).hint(400, 500).grab(true, true).applyTo(scrolledFormText);
GridLayoutFactory.fillDefaults().applyTo(scrolledFormText);
documentationText = scrolledFormText.getFormText();
documentationText.setFont("monospace", JFaceResources.getTextFont());
documentationText.setFont("monospace_inline", JFaceResources.getTextFont());
documentationText.setColor("header", getToolkit().getColors().getColor(IFormColors.TITLE));
documentationText.setFont("header", JFaceResources.getBannerFont());
GridDataFactory.fillDefaults().grab(true, true).applyTo(documentationText);
documentationText.setWhitespaceNormalized(false);
final HyperlinkAdapter hyperlinkListener = createHyperlinkListener();
documentationText.addHyperlinkListener(hyperlinkListener);
argumentsText.addHyperlinkListener(hyperlinkListener);
addDisposeListener(new DisposeListener() {
@Override
public void widgetDisposed(final DisposeEvent e) {
documentationText.removeHyperlinkListener(hyperlinkListener);
argumentsText.removeHyperlinkListener(hyperlinkListener);
}
});
return actualComposite;
}
@Override
protected Composite getControl() {
return (Composite) super.getControl();
}
private HyperlinkAdapter createHyperlinkListener() {
return new HyperlinkAdapter() {
@Override
public void linkActivated(final HyperlinkEvent event) {
final Object href = event.getHref();
if (href instanceof String) {
try {
PlatformUI.getWorkbench().getBrowserSupport().getExternalBrowser()
.openURL(new URL((String) href));
} catch (PartInitException | MalformedURLException e) {
throw new IllegalStateException("Unable to open hyperlink: " + event.getLabel(), e);
}
}
}
};
}
@Override
protected InputLoadingFormComposite.InputJob provideInputCollectingJob() {
return collectingJob;
}
@Override
protected void fillControl(final Object jobResult) {
final Documentation kwSpec = (Documentation) jobResult;
if (getControl() == null || getControl().isDisposed()) {
return;
}
if (kwSpec.isHtml) {
documentationText.setText(kwSpec.text, true, true);
} else {
argumentsText.setText(kwSpec.arguments, true, false);
documentationText.setText(kwSpec.text, false, true);
}
argumentsText.layout();
scrolledFormText.reflow(true);
getControl().layout();
}
private class Documentation {
private String arguments;
private final String text;
private final boolean isHtml;
public Documentation(final KeywordSpecification spec) {
isHtml = spec.canBeConvertedToHtml();
if (isHtml) {
arguments = "";
text = "<form>" + createArgumentsDoc(spec.getArguments()) + spec.getDocumentationAsHtml() + "</form>";
} else {
arguments = "<form>" + createArgumentsDoc(spec.getArguments()) + "</form>";
text = spec.getDocumentation();
}
}
private String createArgumentsDoc(final List<String> arguments) {
final StringBuilder builder = new StringBuilder("<p><b>Arguments</b></p>");
for (final String arg : arguments) {
builder.append("<li>");
builder.append(arg);
builder.append("</li>");
}
return builder.toString();
}
}
}