blob: a43bb6e19115efa6f28f3f77dbc0b1fa38abe805 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 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:
* Lucas Bullen (Red Hat Inc.) - initial implementation.
* Pierre-Yves B. <pyvesdev@gmail.com> - Bug 553376 - Logs preference page does not work on Windows
*******************************************************************************/
package org.eclipse.lsp4e.ui;
import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.lsp4e.ContentTypeToLSPLaunchConfigEntry;
import org.eclipse.lsp4e.ContentTypeToLanguageServerDefinition;
import org.eclipse.lsp4e.LanguageServerPlugin;
import org.eclipse.lsp4e.LanguageServersRegistry;
import org.eclipse.lsp4e.LoggingStreamConnectionProviderProxy;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
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.Link;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.wizards.datatransfer.SmartImportWizard;
public class LoggingPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private final class BooleanMapEditingSupport extends EditingSupport {
private final Map<String, Boolean> map;
private BooleanMapEditingSupport(TableViewer viewer, Map<String, Boolean> map) {
super(viewer);
this.map = map;
}
@Override
protected void setValue(Object element, Object value) {
ContentTypeToLanguageServerDefinition server = (ContentTypeToLanguageServerDefinition)element;
map.put(server.getValue().id, (Boolean)value);
hasLoggingBeenChanged = true;
getViewer().refresh(element);
}
@Override
protected Object getValue(Object element) {
ContentTypeToLanguageServerDefinition server = (ContentTypeToLanguageServerDefinition)element;
return map.get(server.getValue().id);
}
@Override
protected CellEditor getCellEditor(Object element) {
return new CheckboxCellEditor();
}
@Override
protected boolean canEdit(Object element) {
return true;
}
}
private final class BooleanMapLabelProvider extends ColumnLabelProvider {
private final Map<String, Boolean> map;
private BooleanMapLabelProvider(Map<String, Boolean> map) {
super();
this.map = map;
}
@Override
public String getText(Object element) {
return map.getOrDefault(((ContentTypeToLanguageServerDefinition) element).getValue().id, false).booleanValue()
? Messages.PreferencePage_enablementCondition_true
: Messages.PreferencePage_enablementCondition_false;
}
}
private TableViewer languageServerViewer;
private TableViewer launchConfigurationViewer;
private Map<String, Boolean> serverEnableLoggingToFile = new HashMap<>();
private Map<String, Boolean> serverEnableLoggingToConsole = new HashMap<>();
private IPreferenceStore store = LanguageServerPlugin.getDefault().getPreferenceStore();
private boolean hasLoggingBeenChanged = false;
@Override
public void init(IWorkbench workbench) {
//nothing to do
}
@Override
protected Control createContents(Composite parent) {
Composite res = new Composite(parent, SWT.NONE);
res.setLayout(new GridLayout(1, false));
createStaticServersTable(res);
createLaunchConfigurationServersTable(res);
createLoggingContents(res);
updateInputs();
return res;
}
private void createStaticServersTable(Composite res) {
languageServerViewer = new TableViewer(res, SWT.FULL_SELECTION);
languageServerViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
languageServerViewer.setContentProvider(new ArrayContentProvider());
TableViewerColumn launchConfigColumn = new TableViewerColumn(languageServerViewer, 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;
}
});
addLoggingColumnsToViewer(languageServerViewer);
languageServerViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
languageServerViewer.getTable().setHeaderVisible(true);
languageServerViewer.getTable().setLinesVisible(true);
}
private void createLaunchConfigurationServersTable(Composite res) {
launchConfigurationViewer = new TableViewer(res, SWT.FULL_SELECTION);
launchConfigurationViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
launchConfigurationViewer.setContentProvider(new ArrayContentProvider());
TableViewerColumn launchConfigColumn = new TableViewerColumn(launchConfigurationViewer, 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();
}
});
addLoggingColumnsToViewer(launchConfigurationViewer);
launchConfigurationViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
launchConfigurationViewer.getTable().setHeaderVisible(true);
languageServerViewer.getTable().setLinesVisible(true);
}
private void addLoggingColumnsToViewer(TableViewer viewer) {
TableViewerColumn logToFileColumn = new TableViewerColumn(viewer, SWT.NONE);
logToFileColumn.getColumn().setText(Messages.PreferencesPage_logging_toFile_title);
logToFileColumn.getColumn().setWidth(100);
logToFileColumn.setLabelProvider(new BooleanMapLabelProvider(serverEnableLoggingToFile));
logToFileColumn.setEditingSupport(new BooleanMapEditingSupport(viewer, serverEnableLoggingToFile));
TableViewerColumn logToConsoleColumn = new TableViewerColumn(viewer, SWT.NONE);
logToConsoleColumn.getColumn().setText(Messages.PreferencesPage_logging_toConsole_title);
logToConsoleColumn.getColumn().setWidth(125);
logToConsoleColumn.setLabelProvider(new BooleanMapLabelProvider(serverEnableLoggingToConsole));
logToConsoleColumn.setEditingSupport(new BooleanMapEditingSupport(viewer, serverEnableLoggingToConsole));
}
private void createLoggingContents(Composite res) {
Composite loggingComposite = new Composite(res, SWT.NONE);
loggingComposite.setLayout(new GridLayout(3, false));
loggingComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
Label infoLabel = new Label(loggingComposite, SWT.NONE);
infoLabel.setText(Messages.preferencesPage_logging_info);
infoLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
Link logFolderLabel = new Link(loggingComposite, SWT.NONE);
logFolderLabel.setText(NLS.bind(Messages.preferencesPage_logging_fileLogsLocation, LoggingStreamConnectionProviderProxy.getLogDirectory()));
logFolderLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1));
logFolderLabel.addSelectionListener(widgetSelectedAdapter(e -> {
SmartImportWizard importWizard = new SmartImportWizard();
importWizard.setInitialImportSource(LoggingStreamConnectionProviderProxy.getLogDirectory());
WizardDialog dialog = new WizardDialog(logFolderLabel.getShell(), importWizard);
dialog.open();
}));
Label fileLoggingLabel = new Label(loggingComposite, SWT.NONE);
fileLoggingLabel.setText(Messages.PreferencesPage_logging_toFile_description);
Button disableFileLogging = new Button(loggingComposite, SWT.NONE);
disableFileLogging.setText(Messages.PreferencePage_enablementCondition_disableAll);
disableFileLogging.addSelectionListener(widgetSelectedAdapter(e -> {
serverEnableLoggingToFile.forEach((s, b) -> serverEnableLoggingToFile.put(s, false));
hasLoggingBeenChanged = true;
languageServerViewer.refresh();
launchConfigurationViewer.refresh();
}));
Button enableFileLogging = new Button(loggingComposite, SWT.NONE);
enableFileLogging.setText(Messages.PreferencePage_enablementCondition_enableAll);
enableFileLogging.addSelectionListener(widgetSelectedAdapter(e -> {
serverEnableLoggingToFile.forEach((s, b) -> serverEnableLoggingToFile.put(s, true));
hasLoggingBeenChanged = true;
languageServerViewer.refresh();
launchConfigurationViewer.refresh();
}));
Label consoleLoggingLabel = new Label(loggingComposite, SWT.NONE);
consoleLoggingLabel.setText(Messages.PreferencesPage_logging_toConsole_description);
Button disableConsoleLogging = new Button(loggingComposite, SWT.NONE);
disableConsoleLogging.setText(Messages.PreferencePage_enablementCondition_disableAll);
disableConsoleLogging.addSelectionListener(widgetSelectedAdapter(e -> {
serverEnableLoggingToConsole.forEach((s, b) -> serverEnableLoggingToConsole.put(s, false));
hasLoggingBeenChanged = true;
languageServerViewer.refresh();
launchConfigurationViewer.refresh();
}));
Button enableConsoleLogging = new Button(loggingComposite, SWT.NONE);
enableConsoleLogging.setText(Messages.PreferencePage_enablementCondition_enableAll);
enableConsoleLogging.addSelectionListener(widgetSelectedAdapter(e -> {
serverEnableLoggingToConsole.forEach((s, b) -> serverEnableLoggingToConsole.put(s, true));
hasLoggingBeenChanged = true;
languageServerViewer.refresh();
launchConfigurationViewer.refresh();
}));
}
@Override
protected void performDefaults() {
serverEnableLoggingToFile.forEach((s, b) -> serverEnableLoggingToFile.put(s,
store.getBoolean(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(s))));
serverEnableLoggingToConsole.forEach((s, b) -> serverEnableLoggingToConsole.put(s,
store.getBoolean(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(s))));
launchConfigurationViewer.refresh();
languageServerViewer.refresh();
super.performDefaults();
}
private void applyLoggingEnablment() {
serverEnableLoggingToFile.forEach((s, b) -> store.setValue(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(s), b));
serverEnableLoggingToConsole.forEach((s, b) -> store.setValue(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(s), b));
hasLoggingBeenChanged = false;
}
@Override
public boolean performOk() {
if (hasLoggingBeenChanged) {
applyLoggingEnablment();
MessageDialog dialog = new MessageDialog(getShell(), Messages.PreferencesPage_restartWarning_title, null,
Messages.PreferencesPage_restartWarning_message, MessageDialog.WARNING,
new String[] { IDialogConstants.NO_LABEL, Messages.PreferencesPage_restartWarning_restart }, 1);
if (dialog.open() == 1) {
PlatformUI.getWorkbench().restart();
}
}
return super.performOk();
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
updateInputs();
}
private void updateInputs() {
Set<String> languageServerIDs = new HashSet<>();
List<ContentTypeToLSPLaunchConfigEntry> contentTypeToLSPLaunchConfigEntries = new ArrayList<>();
LanguageServersRegistry.getInstance().getContentTypeToLSPLaunches().forEach(o -> {
String id = o.getValue().id;
if (languageServerIDs.add(id)) {
contentTypeToLSPLaunchConfigEntries.add(o);
serverEnableLoggingToFile.put(id, serverEnableLoggingToFile.getOrDefault(id,
store.getBoolean(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(id))));
serverEnableLoggingToConsole.put(id, serverEnableLoggingToConsole.getOrDefault(id,
store.getBoolean(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(id))));
}
});
launchConfigurationViewer.setInput(contentTypeToLSPLaunchConfigEntries);
launchConfigurationViewer.refresh();
languageServerIDs.clear();
List<ContentTypeToLanguageServerDefinition> contentTypeToLanguageServerDefinitions = new ArrayList<>();
LanguageServersRegistry.getInstance().getContentTypeToLSPExtensions().forEach(o -> {
String id = o.getValue().id;
if (languageServerIDs.add(id)) {
contentTypeToLanguageServerDefinitions.add(o);
serverEnableLoggingToFile.put(id, serverEnableLoggingToFile.getOrDefault(id,
store.getBoolean(LoggingStreamConnectionProviderProxy.lsToFileLoggingId(id))));
serverEnableLoggingToConsole.put(id, serverEnableLoggingToConsole.getOrDefault(id,
store.getBoolean(LoggingStreamConnectionProviderProxy.lsToConsoleLoggingId(id))));
}
});
languageServerViewer.setInput(contentTypeToLanguageServerDefinitions);
launchConfigurationViewer.refresh();
}
}