org.eclipse.lsp4e.ui.LanguageServerPreferencePage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.lsp4e.ui.LanguageServerPreferencePage.java

Source

/*******************************************************************************
 * Copyright (c) 2016-2017 Red Hat Inc. 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/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  Mickael Istria (Red Hat Inc.) - initial implementation
 *******************************************************************************/
package org.eclipse.lsp4e.ui;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.lsp4e.ContentTypeToLSPLaunchConfigEntry;
import org.eclipse.lsp4e.ContentTypeToLanguageServerDefinition;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4e.enablement.EnablementTester;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
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.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;

public class LanguageServerPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {

    private LanguageServersRegistry registry;
    private List<ContentTypeToLSPLaunchConfigEntry> workingCopy;
    private Button removeButton;
    private CheckboxTableViewer checkboxViewer;
    private TableViewer viewer;
    private SelectionAdapter contentTypeLinkListener;
    private List<ContentTypeToLanguageServerDefinition> changedDefinitions;

    public LanguageServerPreferencePage() {

        contentTypeLinkListener = new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                if (getContainer() instanceof IWorkbenchPreferenceContainer) {
                    ((IWorkbenchPreferenceContainer) getContainer())
                            .openPage("org.eclipse.ui.preferencePages.ContentTypes", null); //$NON-NLS-1$
                }
            }
        };
    }

    @Override
    public void init(IWorkbench workbench) {
        this.changedDefinitions = new ArrayList<>();
        this.registry = LanguageServersRegistry.getInstance();
    }

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible) {
            this.checkboxViewer.refresh();
        }
    }

    @Override
    protected Control createContents(Composite parent) {
        Composite res = new Composite(parent, SWT.NONE);
        res.setLayout(new GridLayout(2, false));
        Link intro = new Link(res, SWT.WRAP);
        GridDataFactory.swtDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).span(2, 1).hint(400, SWT.DEFAULT)
                .applyTo(intro);
        intro.setText(Messages.PreferencesPage_Intro);
        intro.addSelectionListener(this.contentTypeLinkListener);

        createStaticServersTable(res);

        Link manualServersIntro = new Link(res, SWT.WRAP);
        GridDataFactory.swtDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).span(2, 1).hint(400, SWT.DEFAULT)
                .applyTo(manualServersIntro);
        manualServersIntro.setText(Messages.PreferencesPage_manualServers);
        manualServersIntro.addSelectionListener(this.contentTypeLinkListener);
        viewer = new TableViewer(res);
        viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        viewer.setContentProvider(new ArrayContentProvider());
        workingCopy = new ArrayList<>();
        workingCopy.addAll(LanguageServersRegistry.getInstance().getContentTypeToLSPLaunches());
        TableViewerColumn contentTypeColumn = new TableViewerColumn(viewer, SWT.NONE);
        contentTypeColumn.getColumn().setText(Messages.PreferencesPage_contentType);
        contentTypeColumn.getColumn().setWidth(200);
        contentTypeColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                return ((ContentTypeToLanguageServerDefinition) element).getKey().getName();
            }
        });
        TableViewerColumn launchConfigColumn = new TableViewerColumn(viewer, SWT.NONE);
        launchConfigColumn.getColumn().setText(Messages.PreferencesPage_LaunchConfiguration);
        launchConfigColumn.getColumn().setWidth(300);
        launchConfigColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                return ((ContentTypeToLSPLaunchConfigEntry) element).getLaunchConfiguration().getName();
            }
        });
        TableViewerColumn launchModeColumn = new TableViewerColumn(viewer, SWT.NONE);
        launchModeColumn.getColumn().setText(Messages.PreferencesPage_LaunchMode);
        launchModeColumn.getColumn().setWidth(100);
        launchModeColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                StringBuilder res = new StringBuilder();
                for (String s : ((ContentTypeToLSPLaunchConfigEntry) element).getLaunchModes()) {
                    res.append(s);
                    res.append(',');
                }
                if (res.length() > 0) {
                    res.deleteCharAt(res.length() - 1);
                }
                return res.toString();
            }
        });
        viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        viewer.getTable().setHeaderVisible(true);
        Composite buttonComposite = new Composite(res, SWT.NONE);
        buttonComposite.setLayout(new GridLayout(1, false));
        Button addButton = new Button(buttonComposite, SWT.PUSH);
        addButton.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
        addButton.setText(Messages.PreferencesPage_Add);
        addButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                NewContentTypeLSPLaunchDialog dialog = new NewContentTypeLSPLaunchDialog(getShell());
                if (dialog.open() == IDialogConstants.OK_ID) {
                    workingCopy.add(new ContentTypeToLSPLaunchConfigEntry(dialog.getContentType(),
                            dialog.getLaunchConfiguration(), dialog.getLaunchMode()));
                    viewer.refresh();
                }
                super.widgetSelected(e);
            }
        });
        removeButton = new Button(buttonComposite, SWT.PUSH);
        removeButton.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
        removeButton.setText(Messages.PreferencesPage_Remove);
        removeButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                ISelection sel = viewer.getSelection();
                if (!sel.isEmpty() && sel instanceof IStructuredSelection) {
                    for (Object item : ((IStructuredSelection) sel).toArray()) {
                        workingCopy.remove(item);
                    }
                    viewer.refresh();
                }
            }
        });
        viewer.addSelectionChangedListener(new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                updateButtons();
            }
        });
        viewer.setInput(workingCopy);
        updateButtons();
        return res;
    }

    private void createStaticServersTable(Composite res) {
        Link staticServersIntro = new Link(res, SWT.WRAP);
        GridDataFactory.swtDefaults().align(SWT.FILL, SWT.TOP).grab(true, false).span(2, 1).hint(400, SWT.DEFAULT)
                .applyTo(staticServersIntro);
        staticServersIntro.setText(Messages.PreferencesPage_staticServers);
        staticServersIntro.addSelectionListener(this.contentTypeLinkListener);
        checkboxViewer = CheckboxTableViewer.newCheckList(res, SWT.NONE);
        checkboxViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        checkboxViewer.setContentProvider(new ArrayContentProvider());

        TableViewerColumn enablementColumn = new TableViewerColumn(checkboxViewer, SWT.NONE);
        enablementColumn.getColumn().setText(Messages.PreferencesPage_Enabled);
        enablementColumn.getColumn().setWidth(70);
        enablementColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                return null;
            }
        });

        TableViewerColumn contentTypeColumn = new TableViewerColumn(checkboxViewer, SWT.NONE);
        contentTypeColumn.getColumn().setText(Messages.PreferencesPage_contentType);
        contentTypeColumn.getColumn().setWidth(200);
        contentTypeColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                return ((ContentTypeToLanguageServerDefinition) element).getKey().getName();
            }
        });

        TableViewerColumn launchConfigColumn = new TableViewerColumn(checkboxViewer, SWT.NONE);
        launchConfigColumn.getColumn().setText(Messages.PreferencesPage_languageServer);
        launchConfigColumn.getColumn().setWidth(300);
        launchConfigColumn.setLabelProvider(new ColumnLabelProvider() {
            @Override
            public String getText(Object element) {
                return ((ContentTypeToLanguageServerDefinition) element).getValue().label;
            }
        });

        List<ContentTypeToLanguageServerDefinition> contentTypeToLanguageServerDefinitions = registry
                .getContentTypeToLSPExtensions();
        if (contentTypeToLanguageServerDefinitions.stream()
                .anyMatch(definition -> definition.getEnablementCondition() != null)) {

            TableViewerColumn conditionColumn = new TableViewerColumn(checkboxViewer, SWT.NONE);
            conditionColumn.getColumn().setText(Messages.PreferencesPage_enablementCondition);
            conditionColumn.getColumn().setWidth(150);
            conditionColumn.setLabelProvider(new ColumnLabelProvider() {
                @Override
                public String getText(Object element) {
                    EnablementTester tester = ((ContentTypeToLanguageServerDefinition) element)
                            .getEnablementCondition();

                    if (tester == null) {
                        // table does not support mnemonic
                        return Action.removeMnemonics(IDialogConstants.NO_LABEL);

                    }
                    String extensionStatus = ((ContentTypeToLanguageServerDefinition) element).isExtensionEnabled()
                            ? Messages.PreferencePage_enablementCondition_true
                            : Messages.PreferencePage_enablementCondition_false;
                    return tester.getDescription() + " (" + extensionStatus + ")"; //$NON-NLS-1$ //$NON-NLS-2$
                }

                @Override
                public Color getBackground(Object element) {
                    EnablementTester tester = ((ContentTypeToLanguageServerDefinition) element)
                            .getEnablementCondition();
                    if (tester == null) {
                        return null;
                    }
                    Color red = Display.getDefault().getSystemColor(SWT.COLOR_RED);
                    Color green = Display.getDefault().getSystemColor(SWT.COLOR_GREEN);
                    return ((ContentTypeToLanguageServerDefinition) element).isExtensionEnabled() ? green : red;
                }
            });
        }

        checkboxViewer.setInput(contentTypeToLanguageServerDefinitions);
        checkboxViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
        checkboxViewer.getTable().setHeaderVisible(true);
        checkboxViewer.getTable().setLinesVisible(true);

        this.checkboxViewer.setCheckedElements(contentTypeToLanguageServerDefinitions.stream()
                .filter(definition -> definition.isUserEnabled()).toArray());

        checkboxViewer.addCheckStateListener(new ICheckStateListener() {

            @Override
            public void checkStateChanged(CheckStateChangedEvent event) {
                if (event.getElement() instanceof ContentTypeToLanguageServerDefinition) {
                    ContentTypeToLanguageServerDefinition contentTypeToLanguageServerDefinition = (ContentTypeToLanguageServerDefinition) event
                            .getElement();
                    contentTypeToLanguageServerDefinition.setUserEnabled(event.getChecked());
                    changedDefinitions.add(contentTypeToLanguageServerDefinition);
                }

            }
        });
    }

    protected void updateButtons() {
        this.removeButton.setEnabled(!this.viewer.getSelection().isEmpty());
    }

    @Override
    public boolean performOk() {
        this.registry.setAssociations(this.workingCopy);
        EnableDisableLSJob enableDisableLSJob = new EnableDisableLSJob(changedDefinitions, getEditors());
        enableDisableLSJob.schedule();
        return super.performOk();
    }

    private IEditorReference[] getEditors() {
        IWorkbenchWindow wWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
        if (wWindow != null) {
            IWorkbenchPage wPage = wWindow.getActivePage();
            if (wPage != null) {
                return wPage.getEditorReferences();
            }
        }
        return null;
    }

}