| /*=============================================================================# |
| # 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 static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert; |
| import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit; |
| |
| 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.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| |
| import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin; |
| |
| |
| /** |
| * |
| */ |
| @NonNullByDefault |
| public class DefaultBrowserInformationInput extends BrowserInformationControlInput { |
| |
| |
| public static final int FORMAT_NONE= 0; |
| public static final int FORMAT_TEXT_INPUT= 1; |
| public static final int FORMAT_SOURCE_INPUT= 2; |
| public static final int FORMAT_HTMLBODY_INPUT= 3; |
| public static final int FORMAT_HTMLSOURCE_INPUT= 4; |
| |
| |
| private static @Nullable Formatter FORMATTER; |
| |
| private static class Formatter implements IPropertyChangeListener, Disposable { |
| |
| private String stylesheet= nonNullLateInit(); |
| |
| 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.stylesheet= style; |
| } |
| |
| String format(String content, final int formatting, |
| final int tabSize) { |
| final String stylesheet= this.stylesheet; |
| |
| final StringBuilder sb; |
| switch (formatting) { |
| case FORMAT_NONE: |
| return content; |
| case FORMAT_TEXT_INPUT: |
| content= HTMLPrinter.convertToHTMLContent(content); |
| sb= new StringBuilder(content.length() + stylesheet.length() + 500); |
| sb.append(content); |
| break; |
| case FORMAT_HTMLBODY_INPUT: |
| sb= new StringBuilder(content.length() + stylesheet.length() + 500); |
| sb.append(content); |
| break; |
| case FORMAT_SOURCE_INPUT: |
| content= HTMLPrinter.convertToHTMLContent(content); |
| //$FALL-THROUGH$ |
| case FORMAT_HTMLSOURCE_INPUT: |
| sb= new StringBuilder((int)(content.length() * 1.066) + stylesheet.length() + 500); |
| sb.append("<pre>"); //$NON-NLS-1$ |
| { final String spaces= " ".repeat(tabSize); //$NON-NLS-1$ |
| int fromIdx= 0; |
| int tabIdx; |
| while ((tabIdx= content.indexOf('\t', fromIdx)) >= 0) { |
| sb.append(content, fromIdx, tabIdx); |
| sb.append(spaces); |
| fromIdx= tabIdx + 1; |
| } |
| sb.append(content, fromIdx, content.length()); |
| } |
| sb.append("</pre>"); //$NON-NLS-1$ |
| break; |
| default: |
| throw new IllegalArgumentException("Unsupported format"); //$NON-NLS-1$ |
| } |
| |
| HTMLPrinter.insertPageProlog(sb, 0, this.stylesheet); |
| HTMLPrinter.addPageEpilog(sb); |
| return sb.toString(); |
| } |
| |
| } |
| |
| |
| private final String name; |
| private final String html; |
| |
| |
| public DefaultBrowserInformationInput(final String name, |
| final String content, final int formatting, |
| final int tabSize, |
| final @Nullable BrowserInformationControlInput previous) { |
| super(previous); |
| |
| this.name= nonNullAssert(name); |
| this.html= getFormatter().format(nonNullAssert(content), formatting, tabSize); |
| } |
| |
| public DefaultBrowserInformationInput(final String name, |
| final String content, final int formatting, |
| final @Nullable BrowserInformationControlInput previous) { |
| this(name, content, formatting, 4, previous); |
| } |
| |
| public DefaultBrowserInformationInput(final String name, |
| final String content, final int formatting, |
| final int tabSize) { |
| this(name, content, formatting, tabSize, null); |
| } |
| |
| public DefaultBrowserInformationInput(final String name, |
| final String content, final int formatting) { |
| this(name, content, formatting, 4, null); |
| } |
| |
| |
| protected Formatter getFormatter() { |
| synchronized (DefaultBrowserInformationInput.class) { |
| var formatter= FORMATTER; |
| if (formatter == null) { |
| formatter= new Formatter(); |
| FORMATTER= formatter; |
| } |
| return formatter; |
| } |
| } |
| |
| |
| @Override |
| public String getInputName() { |
| return this.name; |
| } |
| |
| @Override |
| public Object getInputElement() { |
| return this.html; |
| } |
| |
| @Override |
| public String getHtml() { |
| return this.html; |
| } |
| |
| } |