| /******************************************************************************* |
| * Copyright (c) 2008, 2017 xored software, Inc. and others. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0. |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * xored software, Inc. - initial API and Implementation (Alex Panchenko) |
| *******************************************************************************/ |
| package org.eclipse.dltk.ui.formatter; |
| |
| import java.net.URL; |
| |
| import org.eclipse.dltk.ui.util.PixelConverter; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.text.ITextViewerExtension2; |
| import org.eclipse.jface.text.TextViewer; |
| import org.eclipse.jface.text.WhitespaceCharacterPainter; |
| import org.eclipse.jface.text.source.ISourceViewer; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.SashForm; |
| import org.eclipse.swt.custom.ScrolledComposite; |
| import org.eclipse.swt.events.ControlAdapter; |
| import org.eclipse.swt.events.ControlEvent; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Layout; |
| |
| public abstract class FormatterModifyTabPage implements |
| IFormatterModifiyTabPage { |
| |
| protected static final String SHOW_INVISIBLE_PREFERENCE_KEY = "invisible.characters"; //$NON-NLS-1$ |
| |
| private final IFormatterModifyDialog dialog; |
| private ISourceViewer previewViewer; |
| |
| /** |
| * @param dialog |
| */ |
| public FormatterModifyTabPage(IFormatterModifyDialog dialog) { |
| this.dialog = dialog; |
| } |
| |
| private Button fShowInvisibleButton; |
| |
| @Override |
| public Composite createContents(IFormatterControlManager manager, |
| Composite parent) { |
| |
| final int numColumns = 4; |
| |
| if (fPixelConverter == null) { |
| fPixelConverter = new PixelConverter(parent); |
| } |
| |
| final SashForm sashForm = new SashForm(parent, SWT.HORIZONTAL); |
| sashForm.setFont(parent.getFont()); |
| |
| Composite scrollContainer = new Composite(sashForm, SWT.NONE); |
| |
| GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true); |
| scrollContainer.setLayoutData(gridData); |
| |
| GridLayout layout = new GridLayout(2, false); |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| layout.horizontalSpacing = 0; |
| layout.verticalSpacing = 0; |
| scrollContainer.setLayout(layout); |
| |
| ScrolledComposite scroll = new ScrolledComposite(scrollContainer, |
| SWT.V_SCROLL | SWT.H_SCROLL); |
| scroll.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| scroll.setExpandHorizontal(true); |
| scroll.setExpandVertical(true); |
| |
| final Composite settingsContainer = new Composite(scroll, SWT.NONE); |
| settingsContainer.setFont(sashForm.getFont()); |
| |
| scroll.setContent(settingsContainer); |
| |
| settingsContainer.setLayout(new PageLayout(scroll, 400, 400)); |
| settingsContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, |
| true)); |
| |
| Composite settingsPane = new Composite(settingsContainer, SWT.NONE); |
| settingsPane |
| .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); |
| |
| layout = new GridLayout(1, false); |
| layout.verticalSpacing = (int) (1.5 * fPixelConverter |
| .convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING)); |
| layout.horizontalSpacing = fPixelConverter |
| .convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| layout.marginHeight = fPixelConverter |
| .convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
| layout.marginWidth = fPixelConverter |
| .convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
| settingsPane.setLayout(layout); |
| createOptions(manager, settingsPane); |
| |
| settingsContainer.setSize(settingsContainer.computeSize(SWT.DEFAULT, |
| SWT.DEFAULT)); |
| |
| scroll.addControlListener(new ControlAdapter() { |
| @Override |
| public void controlResized(ControlEvent e) { |
| settingsContainer.setSize(settingsContainer.computeSize( |
| SWT.DEFAULT, SWT.DEFAULT)); |
| } |
| }); |
| |
| Label sashHandle = new Label(scrollContainer, SWT.SEPARATOR |
| | SWT.VERTICAL); |
| gridData = new GridData(SWT.RIGHT, SWT.FILL, false, true); |
| sashHandle.setLayoutData(gridData); |
| |
| final Composite previewPane = new Composite(sashForm, SWT.NONE); |
| previewPane.setLayout(createGridLayout(numColumns, true)); |
| previewPane.setFont(sashForm.getFont()); |
| doCreatePreviewPane(previewPane, numColumns); |
| |
| sashForm.setWeights(new int[] { 3, 3 }); |
| return sashForm; |
| } |
| |
| private WhitespaceCharacterPainter whitespaceCharacterPainter = null; |
| |
| protected void updateShowInvisible(boolean value) { |
| if (value) { |
| if (whitespaceCharacterPainter == null) { |
| whitespaceCharacterPainter = new WhitespaceCharacterPainter( |
| previewViewer); |
| ((ITextViewerExtension2) previewViewer) |
| .addPainter(whitespaceCharacterPainter); |
| } |
| } else { |
| if (whitespaceCharacterPainter != null) { |
| ((ITextViewerExtension2) previewViewer) |
| .removePainter(whitespaceCharacterPainter); |
| whitespaceCharacterPainter = null; |
| } |
| } |
| } |
| |
| protected Composite doCreatePreviewPane(Composite composite, int numColumns) { |
| createLabel(numColumns - 1, composite, |
| FormatterMessages.FormatterModifyTabPage_preview_label_text); |
| |
| fShowInvisibleButton = new Button(composite, SWT.CHECK); |
| fShowInvisibleButton |
| .setText(FormatterMessages.FormatterModifyTabPage_showInvisible); |
| fShowInvisibleButton.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, |
| true, false)); |
| fShowInvisibleButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| final boolean newValue = fShowInvisibleButton.getSelection(); |
| updateShowInvisible(newValue); |
| getDialogSettings() |
| .put(SHOW_INVISIBLE_PREFERENCE_KEY, newValue); |
| } |
| }); |
| previewViewer = dialog.getOwner().createPreview(composite); |
| final boolean savedValue = getDialogSettings().getBoolean( |
| SHOW_INVISIBLE_PREFERENCE_KEY); |
| fShowInvisibleButton.setSelection(savedValue); |
| updateShowInvisible(savedValue); |
| |
| if (previewViewer instanceof TextViewer) { |
| GridData gd = createGridData(numColumns, GridData.FILL_BOTH, 0); |
| gd.widthHint = 100; |
| gd.heightHint = 100; |
| ((TextViewer) previewViewer).getControl().setLayoutData(gd); |
| } |
| |
| return composite; |
| } |
| |
| private IDialogSettings getDialogSettings() { |
| return ((FormatterModifyDialog) dialog).fDialogSettings; |
| } |
| |
| @Override |
| public void updatePreview() { |
| if (previewViewer != null) { |
| FormatterPreviewUtils.updatePreview(previewViewer, |
| getPreviewContent(), dialog.getFormatterFactory(), |
| dialog.getPreferences()); |
| } |
| } |
| |
| protected abstract void createOptions(IFormatterControlManager manager, |
| Composite parent); |
| |
| protected URL getPreviewContent() { |
| return null; |
| } |
| |
| /** |
| * Layout used for the settings part. Makes sure to show scrollbars if |
| * necessary. The settings part needs to be layouted on resize. |
| */ |
| private static class PageLayout extends Layout { |
| |
| private final ScrolledComposite fContainer; |
| private final int fMinimalWidth; |
| private final int fMinimalHight; |
| |
| private PageLayout(ScrolledComposite container, int minimalWidth, |
| int minimalHight) { |
| fContainer = container; |
| fMinimalWidth = minimalWidth; |
| fMinimalHight = minimalHight; |
| } |
| |
| @Override |
| public Point computeSize(Composite composite, int wHint, int hHint, |
| boolean force) { |
| if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) { |
| return new Point(wHint, hHint); |
| } |
| |
| int x = fMinimalWidth; |
| int y = fMinimalHight; |
| Control[] children = composite.getChildren(); |
| for (int i = 0; i < children.length; i++) { |
| Point size = children[i].computeSize(SWT.DEFAULT, SWT.DEFAULT, |
| force); |
| x = Math.max(x, size.x); |
| y = Math.max(y, size.y); |
| } |
| |
| Rectangle area = fContainer.getClientArea(); |
| if (area.width > x) { |
| fContainer.setExpandHorizontal(true); |
| } else { |
| fContainer.setExpandHorizontal(false); |
| } |
| |
| if (area.height > y) { |
| fContainer.setExpandVertical(true); |
| } else { |
| fContainer.setExpandVertical(false); |
| } |
| |
| if (wHint != SWT.DEFAULT) { |
| x = wHint; |
| } |
| if (hHint != SWT.DEFAULT) { |
| y = hHint; |
| } |
| |
| return new Point(x, y); |
| } |
| |
| @Override |
| public void layout(Composite composite, boolean force) { |
| Rectangle rect = composite.getClientArea(); |
| Control[] children = composite.getChildren(); |
| for (int i = 0; i < children.length; i++) { |
| children[i].setSize(rect.width, rect.height); |
| } |
| } |
| } |
| |
| /* |
| * Convenience method to create a label. |
| */ |
| protected static Label createLabel(int numColumns, Composite parent, |
| String text) { |
| return createLabel(numColumns, parent, text, GridData.FILL_HORIZONTAL); |
| } |
| |
| /* |
| * Convenience method to create a label |
| */ |
| protected static Label createLabel(int numColumns, Composite parent, |
| String text, int gridDataStyle) { |
| final Label label = new Label(parent, SWT.WRAP); |
| label.setFont(parent.getFont()); |
| label.setText(text); |
| |
| PixelConverter pixelConverter = new PixelConverter(parent); |
| label.setLayoutData(createGridData(numColumns, gridDataStyle, |
| pixelConverter.convertHorizontalDLUsToPixels(150))); |
| return label; |
| } |
| |
| /* |
| * Create a GridLayout with the default margin and spacing settings, as well |
| * as the specified number of columns. |
| */ |
| protected GridLayout createGridLayout(int numColumns, boolean margins) { |
| final GridLayout layout = new GridLayout(numColumns, false); |
| layout.verticalSpacing = fPixelConverter |
| .convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); |
| layout.horizontalSpacing = fPixelConverter |
| .convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING); |
| if (margins) { |
| layout.marginHeight = fPixelConverter |
| .convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); |
| layout.marginWidth = fPixelConverter |
| .convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); |
| } else { |
| layout.marginHeight = 0; |
| layout.marginWidth = 0; |
| } |
| return layout; |
| } |
| |
| /* |
| * Convenience method to create a GridData. |
| */ |
| protected static GridData createGridData(int numColumns, int style, |
| int widthHint) { |
| final GridData gd = new GridData(style); |
| gd.horizontalSpan = numColumns; |
| gd.widthHint = widthHint; |
| return gd; |
| } |
| |
| /** |
| * A pixel converter for layout calculations |
| */ |
| protected PixelConverter fPixelConverter; |
| |
| } |