blob: 5bf869cd043ab972d96e87c24968dd823ffaf19e [file] [log] [blame]
/*=============================================================================#
# Copyright (c) 2008, 2021 Stephan Wahlbrink and others.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License 2.0 which is available at
# https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
# which is available at https://www.apache.org/licenses/LICENSE-2.0.
#
# SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
#
# Contributors:
# Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
#=============================================================================*/
package org.eclipse.statet.ecommons.text.ui;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jface.internal.text.html.BrowserInformationControlInput;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.statet.jcommons.lang.Disposable;
import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;
/**
*
*/
public class DefaultBrowserInformationInput extends BrowserInformationControlInput {
private static Formatter FORMATTER;
private static class Formatter implements IPropertyChangeListener, Disposable {
private static final Pattern TAB_PATTERN= Pattern.compile("\\\t"); //$NON-NLS-1$
private String STYLE_SHEET;
public Formatter() {
JFaceResources.getFontRegistry().addListener(this);
LTKUIPlugin.getInstance().addStoppingListener(this);
updateStyleSheet();
}
@Override
public void dispose() {
JFaceResources.getFontRegistry().removeListener(this);
FORMATTER= null;
}
@Override
public void propertyChange(final PropertyChangeEvent event) {
if (event.getProperty().equals(JFaceResources.DIALOG_FONT)) {
updateStyleSheet();
}
}
private void updateStyleSheet() {
String style =
// Font definitions
"html { font-family: sans-serif; font-size: 9pt; font-style: normal; font-weight: normal; }\n"+
"body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size: 1em; }\n"+
"pre { font-family: monospace; }\n"+
// Margins
"html { margin: 0px; padding: 0px }"+
"body { overflow: auto; margin-top: 0.25em; margin-bottom: 0.5em; margin-left: 0.25em; margin-right: 0.25em; }\n"+
"h1 { margin-top: 0.3em; margin-bottom: 0.04em; }\n"+
"h2 { margin-top: 2em; margin-bottom: 0.25em; }\n"+
"h3 { margin-top: 1.7em; margin-bottom: 0.25em; }\n"+
"h4 { margin-top: 2em; margin-bottom: 0.3em; }\n"+
"h5 { margin-top: 0px; margin-bottom: 0px; }\n"+
"p { margin-top: 1em; margin-bottom: 1em; }\n"+
// "pre { margin-left: 0.6em; }\n"+
"ul { margin-top: 0px; margin-bottom: 1em; }\n"+
"li { margin-top: 0px; margin-bottom: 0px; }\n"+
"li p { margin-top: 0px; margin-bottom: 0px; }\n"+
"ol { margin-top: 0px; margin-bottom: 1em; }\n"+
"dl { margin-top: 0px; margin-bottom: 1em; }\n"+
"dt { margin-top: 0px; margin-bottom: 0px; font-weight: bold; }\n"+
"dd { margin-top: 0px; margin-bottom: 0px; }\n"+
// Styles and colors
"a:link { color: #0000FF; }\n"+
"a:hover { color: #000080; }\n"+
"a:visited { text-decoration: underline; }\n"+
"h4 { font-style: italic; }\n"+
"strong { font-weight: bold; }\n"+
"em { font-style: italic; }\n"+
"var { font-style: italic; }\n"+
"th { font-weight: bold; }\n";
try {
final FontData[] fontData= JFaceResources.getFontRegistry().getFontData(JFaceResources.DIALOG_FONT);
if (fontData != null && fontData.length > 0) {
style= style.replace("9pt", fontData[0].getHeight()+"pt");
style= style.replace("sans-serif", "sans-serif, '"+fontData[0].getName()+"'");
}
}
catch (final Throwable e) {
}
this.STYLE_SHEET= style;
}
String format(String content, final int formatting) {
final StringBuilder s;
switch (formatting) {
case FORMAT_NONE:
return content;
case FORMAT_TEXT_INPUT:
content= HTMLPrinter.convertToHTMLContent(content);
s= new StringBuilder(content.length() + 1000);
s.append(content);
break;
case FORMAT_SOURCE_INPUT:
content= HTMLPrinter.convertToHTMLContent(content);
final Matcher matcher= TAB_PATTERN.matcher(content);
if (matcher.find()) {
content= matcher.replaceAll(" "); //$NON-NLS-1$
}
s= new StringBuilder(content.length() + 1000);
s.append("<pre>"); //$NON-NLS-1$
s.append(content);
s.append("</pre>"); //$NON-NLS-1$
break;
case FORMAT_HTMLBODY_INPUT:
s= new StringBuilder(content.length() + 1000);
s.append(content);
break;
default:
throw new IllegalArgumentException("Unsupported format"); //$NON-NLS-1$
}
HTMLPrinter.insertPageProlog(s, 0, this.STYLE_SHEET);
HTMLPrinter.addPageEpilog(s);
return s.toString();
}
}
public static final int FORMAT_NONE= 0;
public static final int FORMAT_HTMLBODY_INPUT= 1;
public static final int FORMAT_TEXT_INPUT= 2;
public static final int FORMAT_SOURCE_INPUT= 3;
private final String fName;
private final String fHtml;
public DefaultBrowserInformationInput(final BrowserInformationControlInput previous, final String name, final String content, final int formatting) {
super(previous);
this.fName= name;
this.fHtml= getFormatter().format(content, formatting);
}
protected Formatter getFormatter() {
synchronized (DefaultBrowserInformationInput.class) {
if (FORMATTER == null) {
FORMATTER= new Formatter();
}
return FORMATTER;
}
}
@Override
public String getInputName() {
return this.fName;
}
@Override
public Object getInputElement() {
return this.fHtml;
}
@Override
public String getHtml() {
return this.fHtml;
}
}