blob: 212d07b95ecf385d7df77b7bf846be9570217813 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2015 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.ide;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.DefaultScope;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
/**
* A class to handle editing of the line delimiter preferences in core.
*
* @since 3.1
*/
public class LineDelimiterEditor {
private Button defaultButton;
private Button otherButton;
private Combo choiceCombo;
/**
* The project whose preferences should be set. In some cases this class
* will be used to edit project preferences. If project is null, then we
* are editing workspace preferences.
*/
private IProject project;
private Group group;
/**
* Creates a new line delimiter editor for workspace.
*
* @param composite
* the parent of the field editor's control
*/
public LineDelimiterEditor(Composite composite) {
this(composite, null);
}
/**
* Creates a new line delimiter editor for the given project.
*
* @param composite
* the parent of the field editor's control
* @param project
* the project to set preferences on
*/
public LineDelimiterEditor(Composite composite, IProject project) {
this.project = project;
createControl(composite);
}
/**
* Creates this field editor's main control containing all of its basic
* controls.
*
* @param parent
* the parent control
*/
private void createControl(Composite parent) {
Font font = parent.getFont();
group = new Group(parent, SWT.NONE);
GridData data = new GridData(GridData.FILL_HORIZONTAL);
group.setLayoutData(data);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
group.setLayout(layout);
group.setText(IDEWorkbenchMessages.IDEWorkspacePreference_fileLineDelimiter);
group.setFont(font);
SelectionAdapter buttonListener = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
if (e.widget.equals(defaultButton)) {
updateState(true);
} else {
updateState(false);
}
}
};
defaultButton = new Button(group, SWT.RADIO);
String key = getKeyForValue(getDefaultValue());
if (project == null) {
defaultButton.setText(NLS.bind(IDEWorkbenchMessages.IDEWorkspacePreference_defaultLineDelim, key));
} else {
defaultButton.setText(NLS.bind(IDEWorkbenchMessages.IDEWorkspacePreference_defaultLineDelimProj, key));
}
data = new GridData();
data.horizontalSpan = 2;
defaultButton.setLayoutData(data);
defaultButton.addSelectionListener(buttonListener);
defaultButton.setFont(font);
otherButton = new Button(group, SWT.RADIO);
otherButton.setText(IDEWorkbenchMessages.IDEWorkspacePreference_otherLineDelim);
otherButton.addSelectionListener(buttonListener);
otherButton.setFont(font);
choiceCombo = new Combo(group, SWT.NONE | SWT.READ_ONLY);
data = new GridData();
choiceCombo.setFont(font);
choiceCombo.setLayoutData(data);
}
/**
* Load the list items from core and update the state of the buttons to
* match what the preference is currently set to.
*/
public void doLoad() {
if (choiceCombo != null) {
choiceCombo.setItems(getChoices());
String resourcePreference = getStoredValue(getPreferences(project));
selectChoice(getKeyForValue(resourcePreference));
updateState(resourcePreference == null);
}
}
/**
* Initializes this field editor with the preference default value.
*/
public void loadDefault() {
if (choiceCombo != null) {
updateState(true);
}
}
private String getDefaultValue() {
String value = null;
if (project != null) {
value = getStoredValue(getPreferences(null));
}
if (value == null) {
value = getStoredValue(Platform.getPreferencesService().getRootNode().node(DefaultScope.SCOPE));
}
return value != null ? value : System.getProperty(Platform.PREF_LINE_SEPARATOR);
}
private String getKeyForValue(String value) {
Map<String, String> knownValues = Platform.knownPlatformLineSeparators();
for (Entry<String, String> entry : knownValues.entrySet()) {
String key = entry.getKey();
if (entry.getValue().equals(value)) {
return key;
}
}
return null;
}
/**
* Returns the value that is currently stored for the line delimiter.
*
* @param node
* preferences node from which the value should be read
* @return the currently stored line delimiter
*/
private String getStoredValue(Preferences node) {
try {
// be careful looking up for our node so not to create any nodes as side effect
if (node.nodeExists(Platform.PI_RUNTIME))
return node.node(Platform.PI_RUNTIME).get(Platform.PREF_LINE_SEPARATOR, null);
} catch (BackingStoreException e) {
// ignore
}
return null;
}
/**
* Answer the <code>Preferences</code> for the receiver, this will be a
* project preferences if the receiver is editing project preferences,
* otherwise instance preferences.
*
* @param project
* the project for which the line editor will be modified
* @return the preferences
*/
private Preferences getPreferences(IProject project) {
if (project != null) {
return Platform.getPreferencesService().getRootNode().node(ProjectScope.SCOPE).node(project.getName());
}
return Platform.getPreferencesService().getRootNode().node(InstanceScope.SCOPE);
}
/**
* Returns the default setting for the object being shown.
*
* @return the default setting for the object being shown
*/
private String[] getChoices() {
Set keys = Platform.knownPlatformLineSeparators().keySet();
String[] keyArray = new String[keys.size()];
keys.toArray(keyArray);
return keyArray;
}
private void updateState(boolean useDefault) {
if (useDefault) {
defaultButton.setSelection(true);
otherButton.setSelection(false);
choiceCombo.setEnabled(false);
selectChoice(getKeyForValue(getDefaultValue()));
} else {
defaultButton.setSelection(false);
otherButton.setSelection(true);
choiceCombo.setEnabled(true);
}
}
/**
* Select the item in the combo that matches the current preferences
* setting. NOTE: not handling the case where two platform line separators
* are defined with the same value. Assumption is that they are unique and
* the key will be modified to represent that. E.g. a key might be Mac OS
* 10/Linux if the same value is required for two platforms.
*/
private void selectChoice(String selection) {
String[] items = choiceCombo.getItems();
for (int i = 0; i < items.length; i++) {
String item = items[i];
if (item.equals(selection)) {
choiceCombo.select(i);
break;
}
}
}
/**
* Store the currently selected line delimiter value in the preference
* store.
*/
public void store() {
String val;
if (defaultButton.getSelection() || choiceCombo.getText().equals("")) { //$NON-NLS-1$
val = null;
} else {
Map lineSeparators = Platform.knownPlatformLineSeparators();
val = (String) lineSeparators.get(choiceCombo.getText());
}
Preferences node = getPreferences(project).node(Platform.PI_RUNTIME);
if (val == null) {
node.remove(Platform.PREF_LINE_SEPARATOR);
} else {
node.put(Platform.PREF_LINE_SEPARATOR, val);
}
try {
node.flush();
} catch (BackingStoreException e) {
IDEWorkbenchPlugin.log(e.getMessage(), e);
}
}
/**
* Set whether or not the controls in the field editor are enabled.
*
* @param enabled
* The enabled state.
*/
public void setEnabled(boolean enabled) {
group.setEnabled(enabled);
for (Control child : group.getChildren()) {
child.setEnabled(enabled);
}
}
}