melnorme.lang.ide.ui.text.AbstractLangBasicSourceViewerConfiguration.java Source code

Java tutorial

Introduction

Here is the source code for melnorme.lang.ide.ui.text.AbstractLangBasicSourceViewerConfiguration.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Bruno Medeiros and other Contributors.
 * 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:
 *     Bruno Medeiros - initial API and implementation
 *******************************************************************************/
package melnorme.lang.ide.ui.text;

import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull;
import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants;

import melnorme.lang.ide.core.TextSettings_Actual;
import melnorme.lang.ide.core.TextSettings_Actual.LangPartitionTypes;
import melnorme.lang.ide.ui.CodeFormatterConstants;
import melnorme.lang.ide.ui.EditorSettings_Actual;
import melnorme.lang.ide.ui.LangUIMessages;
import melnorme.lang.ide.ui.LangUIPlugin;
import melnorme.lang.ide.ui.editor.ProjectionViewerExt;
import melnorme.lang.ide.ui.editor.ViewerColorUpdater;
import melnorme.lang.ide.ui.text.coloring.StylingPreferences;
import melnorme.lang.ide.ui.text.coloring.TokenRegistry;
import melnorme.util.swt.jface.text.ColorManager2;
import melnorme.utilbox.collections.ArrayList2;
import melnorme.utilbox.misc.ArrayUtil;
import melnorme.utilbox.ownership.IDisposable;

/**
 * Abstract SourceViewConfiguration
 * Has code to help manage the configured scanners, and let respond to preference changes.
 */
public abstract class AbstractLangBasicSourceViewerConfiguration extends TextSourceViewerConfiguration {

    protected final IPreferenceStore preferenceStore;
    protected final ColorManager2 colorManager;
    protected final StylingPreferences stylingPrefs;

    public AbstractLangBasicSourceViewerConfiguration(IPreferenceStore preferenceStore) {
        super(assertNotNull(preferenceStore));
        this.preferenceStore = preferenceStore;
        this.colorManager = assertNotNull(init_ColorManager());
        this.stylingPrefs = assertNotNull(init_StylePreferences());
    }

    protected ColorManager2 init_ColorManager() {
        return LangUIPlugin.getInstance().getColorManager();
    }

    protected StylingPreferences init_StylePreferences() {
        return EditorSettings_Actual.getStylingPreferences();
    }

    protected final ColorManager2 getColorManager() {
        return colorManager;
    }

    public IPreferenceStore getPreferenceStore() {
        return preferenceStore;
    }

    public void handlePropertyChange(PropertyChangeEvent event, IPreferenceStore prefStore,
            SourceViewer sourceViewer) {
        assertTrue(prefStore == getPreferenceStore());
        String property = event.getProperty();
        updateIndentationSettings(sourceViewer, property);
    }

    /* ----------------- scanners / partitioning ----------------- */

    @Override
    public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
        return TextSettings_Actual.PARTITIONING_ID;
    }

    @Override
    public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
        return ArrayUtil.map(getPartitionTypes(), obj -> obj.getId(), String.class);
    }

    public LangPartitionTypes[] getPartitionTypes() {
        return TextSettings_Actual.LangPartitionTypes.values();
    }

    @Override
    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
        PresentationReconciler reconciler = createPresentationReconciler();
        reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
        setupPresentationReconciler(reconciler, sourceViewer);
        return reconciler;
    }

    protected PresentationReconciler createPresentationReconciler() {
        return new PresentationReconciler();
    }

    protected void setupPresentationReconciler(PresentationReconciler reconciler, ISourceViewer sourceViewer) {
        // Must be called from UI thread
        assertTrue(Display.getCurrent() != null);

        // Create a token registry for given sourceViewer
        TokenRegistry tokenRegistry = new TokenRegistry(colorManager, stylingPrefs) {
            @Override
            protected void handleTokenModified(Token token) {
                sourceViewer.invalidateTextPresentation();
            }
        };
        addConfigurationScopedOwned(sourceViewer, tokenRegistry);

        ArrayList2<AbstractLangScanner> scanners = new ArrayList2<>();

        for (LangPartitionTypes partitionType : getPartitionTypes()) {

            String contentType = partitionType.getId();
            AbstractLangScanner scanner = createScannerFor(Display.getCurrent(), partitionType, tokenRegistry);
            scanners.add(scanner);

            DefaultDamagerRepairer dr = getDamagerRepairer(scanner, contentType);
            reconciler.setDamager(dr, contentType);
            reconciler.setRepairer(dr, contentType);
        }

    }

    @SuppressWarnings("unused")
    protected DefaultDamagerRepairer getDamagerRepairer(AbstractLangScanner scanner, String contentType) {
        return new DefaultDamagerRepairer(scanner);
    }

    protected void addConfigurationScopedOwned(ISourceViewer sourceViewer, IDisposable tokenStore) {
        if (sourceViewer instanceof ProjectionViewerExt) {
            ProjectionViewerExt viewerExt = (ProjectionViewerExt) sourceViewer;
            viewerExt.addConfigurationOwned(tokenStore);
        } else {
            sourceViewer.getTextWidget().addDisposeListener(e -> tokenStore.dispose());
        }
    }

    protected abstract AbstractLangScanner createScannerFor(Display current, LangPartitionTypes partitionType,
            TokenRegistry tokenStore);

    public String getFontPropertyPreferenceKey() {
        return JFaceResources.TEXT_FONT;
    }

    /* ----------------- TextViewer ----------------- */

    @Override
    public int getTabWidth(ISourceViewer sourceViewer) {
        if (fPreferenceStore == null)
            return super.getTabWidth(sourceViewer);
        return fPreferenceStore.getInt(CodeFormatterConstants.FORMATTER_TAB_SIZE.key);
    }

    protected void updateIndentationSettings(SourceViewer sourceViewer, String property) {
        if (CodeFormatterConstants.FORMATTER_TAB_SIZE.key.equals(property)) {
            StyledText textWidget = sourceViewer.getTextWidget();
            int tabWidth = getTabWidth(sourceViewer);
            textWidget.setTabs(tabWidth);
        }
    }

    /* ----------------- Presentation UI controls ----------------- */

    @Override
    public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
        return new IInformationControlCreator() {
            @Override
            public IInformationControl createInformationControl(Shell parent) {
                return new DefaultInformationControl(parent, false);
            }
        };
    }

    protected IInformationControlCreator getInformationControl_ContentAsssist(final String statusFieldText) {
        return new IInformationControlCreator() {
            @Override
            public IInformationControl createInformationControl(Shell parent) {
                return new DefaultInformationControl(parent, statusFieldText);
            }
        };
    }

    /* -----------------  ----------------- */

    public static final String getAdditionalInfoAffordanceString() {
        IPreferenceStore store = EditorsUI.getPreferenceStore();
        if (!store.getBoolean(AbstractDecoratedTextEditorPreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE)) {
            return null;
        }

        return LangUIMessages.SourceHover_additionalInfo_affordance;
    }

    public static ContentAssistant setupSimpleContentAssistant(IContentAssistProcessor cap, String[] contentTypes) {
        ContentAssistant ca = new ContentAssistant();
        ca.enableAutoActivation(true);
        ca.enableAutoInsert(true);

        for (String partitionType : contentTypes) {
            ca.setContentAssistProcessor(cap, partitionType);
        }

        return ca;
    }

    /* -----------------  ----------------- */

    public void configureViewer(ProjectionViewerExt sourceViewer) {
        StyledText textWidget = sourceViewer.getTextWidget();
        if (textWidget != null) {
            textWidget.setFont(JFaceResources.getFont(getFontPropertyPreferenceKey()));
            // TODO: respond to font changes
        }

        new ViewerColorUpdater(fPreferenceStore, sourceViewer).configureViewer();
    }

}