package org.erlide.ui.prefs.plugin;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.DialogPage;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.xtext.xbase.lib.Pair;
import org.erlide.ui.internal.ErlideUIPlugin;
import org.erlide.ui.util.StatusInfo;
import org.erlide.util.ErlLogger;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import com.google.common.collect.Lists;
public abstract class ErlidePreferencePage extends PreferencePage {
protected static List<String> getPreferences(final String dialogKey,
final String[] keys, final String[] defaults) {
final List<String> l = new ArrayList<>(keys.length);
final Preferences node = ErlideUIPlugin.getPrefsNode();
for (int i = 0; i < keys.length; ++i) {
final String s = node.get(dialogKey + "/" + keys[i], //$NON-NLS-1$
defaults[i]);
l.add(s);
}
return l;
}
protected static void addKeysAndPrefs(final String dialogKey, final String[] keys,
final String[] defaults, final Map<String, String> m) {
final List<String> prefs = getPreferences(dialogKey, keys, defaults);
for (int i = 0; i < keys.length; ++i) {
m.put(keys[i], prefs.get(i));
}
}
public void setToPreferences(final String[] keys, final String[] defaults,
final List<Button> buttons) {
final List<String> p = getPreferences(getDialogPreferenceKey(), keys, defaults);
final List<Boolean> l = getBooleanPreferences(p);
for (int i = 0; i < l.size(); ++i) {
final boolean b = l.get(i);
buttons.get(i).setSelection(b);
}
}
@SuppressWarnings("boxing")
protected static List<Boolean> getBooleanPreferences(final List<String> p) {
final List<Boolean> l = new ArrayList<>(p.size());
for (final String i : p) {
l.add(!"0".equals(i) && !"false".equals(i)); //$NON-NLS-1$ //$NON-NLS-2$
}
return l;
}
public static IStatus validatePositiveNumber(final String number) {
final StatusInfo status = new StatusInfo();
if (number.length() == 0) {
status.setError(ErlEditorMessages.ErlEditorPreferencePage_empty_input);
} else {
try {
final int value = Integer.parseInt(number);
if (value < 0) {
status.setError(MessageFormat.format(
ErlEditorMessages.ErlEditorPreferencePage_invalid_input,
(Object[]) new String[] { number }));
}
} catch (final NumberFormatException e) {
status.setError(MessageFormat.format(
ErlEditorMessages.ErlEditorPreferencePage_invalid_input,
(Object[]) new String[] { number }));
}
}
return status;
}
/**
* Applies the status to the status line of a dialog page.
*
* @param page
* the dialog page
* @param status
* the status
*/
public static void applyToStatusLine(final DialogPage page, final IStatus status) {
String message = status.getMessage();
switch (status.getSeverity()) {
case IStatus.OK:
page.setMessage(message, IMessageProvider.NONE);
page.setErrorMessage(null);
break;
case IStatus.WARNING:
page.setMessage(message, IMessageProvider.WARNING);
page.setErrorMessage(null);
break;
case IStatus.INFO:
page.setMessage(message, IMessageProvider.INFORMATION);
page.setErrorMessage(null);
break;
default:
if (message.length() == 0) {
message = null;
}
page.setMessage(null);
page.setErrorMessage(message);
break;
}
}
protected Collection<Text> fNumberFields = Lists.newArrayList();
private final ModifyListener fNumberFieldListener = new ModifyListener() {
@Override
public void modifyText(final ModifyEvent e) {
numberFieldChanged((Text) e.widget);
}
};
public ErlidePreferencePage() {
super();
}
public ErlidePreferencePage(final String title) {
super(title);
}
public ErlidePreferencePage(final String title, final ImageDescriptor image) {
super(title, image);
}
@Override
public boolean performOk() {
putPreferences();
try {
final Preferences node = ErlideUIPlugin.getPrefsNode();
node.flush();
} catch (final BackingStoreException e) {
ErlLogger.warn(e);
}
return true;
}
protected abstract void putPreferences();
protected void putBooleanPreferences(final String[] keys,
final List<Button> buttons) {
final Preferences node = ErlideUIPlugin.getPrefsNode();
for (int i = 0; i < keys.length; ++i) {
final boolean b = buttons.get(i).getSelection();
node.putBoolean(getDialogPreferenceKey() + "/" + keys[i], b); //$NON-NLS-1$
}
}
protected void setToDefaults(final String[] keys, final String[] defaults,
final List<Button> buttons) {
for (int i = 0; i < keys.length; ++i) {
buttons.get(i).setSelection(!defaults[i].equals("0")); //$NON-NLS-1$
}
}
protected void addCheckboxes(final Composite composite, final String[] nlStrings,
final List<Button> list) {
for (final String s : nlStrings) {
final Button b = addCheckBox(composite, s);
list.add(b);
}
}
protected Button addCheckBox(final Composite composite, final String label) {
final Button checkBox = new Button(composite, SWT.CHECK);
checkBox.setText(label);
return checkBox;
}
protected Pair<Button, String> addCheckBox(final Composite parent, final String label,
final String key, final int indentation) {
final Button checkBox = new Button(parent, SWT.CHECK);
checkBox.setText(label);
final GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalIndent = indentation;
gd.horizontalSpan = 2;
checkBox.setLayoutData(gd);
return new Pair<>(checkBox, getDialogPreferenceKey() + "/" + key);
}
protected abstract String getDialogPreferenceKey();
protected Pair<Text, String> addTextField(final Composite composite,
final String label, final String key, final int textLimit,
final int indentation, final boolean isNumber) {
final Label labelControl = new Label(composite, SWT.NONE);
labelControl.setText(label);
GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.horizontalIndent = indentation;
labelControl.setLayoutData(gd);
final Text textControl = new Text(composite, SWT.BORDER | SWT.SINGLE);
gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
gd.widthHint = convertWidthInCharsToPixels(textLimit + 1);
textControl.setLayoutData(gd);
textControl.setTextLimit(textLimit);
if (isNumber) {
textControl.addModifyListener(getNumberFieldListener());
fNumberFields.add(textControl);
}
return new Pair<>(textControl, getDialogPreferenceKey() + "/" + key);
}
protected void numberFieldChanged(final Text textControl) {
final String number = textControl.getText();
final IStatus status = validatePositiveNumber(number);
updateStatus(status);
}
protected void updateStatus(final IStatus status0) {
IStatus status = status0;
if (!status.matches(IStatus.ERROR)) {
for (final Text text : fNumberFields) {
final IStatus s = validatePositiveNumber(text.getText());
status = s.getSeverity() > status.getSeverity() ? s : status;
}
}
setValid(!status.matches(IStatus.ERROR));
applyToStatusLine(this, status);
}
public ModifyListener getNumberFieldListener() {
return fNumberFieldListener;
}
protected void putIntPreferences(final String[] keys, final List<Text> textFields) {
final Preferences node = ErlideUIPlugin.getPrefsNode();
for (int i = 0; i < keys.length; ++i) {
int n;
n = Integer.parseInt(textFields.get(i).getText());
node.putInt(getDialogPreferenceKey() + "/" + keys[i], n); //$NON-NLS-1$
}
}
protected List<String> getPreferences(final String[] indentKeys,
final String[] indentDefaults) {
return getPreferences(getDialogPreferenceKey(), indentKeys, indentDefaults);
}
}