/*******************************************************************************
* Copyright (c) 2009, 2011 Alena Laskavaia 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:
* Alena Laskavaia - initial API and implementation
* IBM Corporation
*******************************************************************************/
package org.eclipse.cdt.codan.internal.ui.widgets;
import java.io.File;
import org.eclipse.cdt.codan.core.model.CodanSeverity;
import org.eclipse.cdt.codan.core.model.IProblem;
import org.eclipse.cdt.codan.core.model.IProblemWorkingCopy;
import org.eclipse.cdt.codan.core.param.FileScopeProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreference;
import org.eclipse.cdt.codan.core.param.IProblemPreferenceCompositeDescriptor;
import org.eclipse.cdt.codan.core.param.LaunchModeProblemPreference;
import org.eclipse.cdt.codan.core.param.ListProblemPreference;
import org.eclipse.cdt.codan.internal.ui.CodanUIMessages;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.ListEditor;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
/**
* Composite to show problem preferences
*
*/
public class ParametersComposite extends Composite {
private static final String PREF_ENABLED = "enabled"; //$NON-NLS-1$
private static final String PREF_SEVERITY = "severity"; //$NON-NLS-1$
private static final String PREF_MESSAGE = "message"; //$NON-NLS-1$
public static final String NO_CHANGE = CodanUIMessages.ParametersComposite_DoNotChange;
private FieldEditorPreferencePage page;
private IProblem problem;
private PreferenceStore prefStore;
/**
* @param parent
* @param problem
* @param style
*/
public ParametersComposite(Composite parent, final IProblem problem) {
super(parent, SWT.NONE);
if (problem == null)
throw new NullPointerException();
this.setLayout(new GridLayout(2, false));
this.problem = problem;
this.prefStore = new PreferenceStore();
page = new FieldEditorPreferencePage(FieldEditorPreferencePage.GRID) {
@Override
protected void createFieldEditors() {
noDefaultAndApplyButton();
((GridLayout) getFieldEditorParent().getLayout()).numColumns = 2;
addField(new BooleanFieldEditor(PREF_ENABLED, CodanUIMessages.ParametersComposite_IsEnabled, getFieldEditorParent()));
String[][] entries = { { CodanSeverity.Error.toTranslatableString(), CodanSeverity.Error.toString() }, //
{ CodanSeverity.Warning.toTranslatableString(), CodanSeverity.Warning.toString() }, //
{ CodanSeverity.Info.toTranslatableString(), CodanSeverity.Info.toString() }, //
{ NO_CHANGE, NO_CHANGE }, //
};
addField(new ComboFieldEditor(PREF_SEVERITY, CodanUIMessages.ParametersComposite_Severity, entries, getFieldEditorParent()));
StringFieldEditor messagePatternEditor = new StringFieldEditor(PREF_MESSAGE,
CodanUIMessages.ParametersComposite_MessagePattern, getFieldEditorParent());
// We are using read-only text field for message pattern to allow copy to clipboard.
makeUneditable(messagePatternEditor);
addField(messagePatternEditor);
IProblemPreference pref = problem.getPreference();
createFieldEditorsForParameters(pref);
}
private void makeUneditable(StringFieldEditor editor) {
/*
* Here we are doing 2 things to make a text control "uneditable":
* 1. 'setUneditable(false)' the problem with with just doing this is that
* the background of the text control doesn't change, and it looks like
* an editable one. This is confusing to the user.
* 2. Getting the background of a label control and applying it
* to the "uneditable" text control. This way it is easier to figure out that
* the contents of the text control cannot be changed.
* Why not just setEnable(false)? Because it changes the text of the text control
* to light gray, making it difficult to read. Also, users cannot select and copy
* text from a disabled text field.
*/
Color background = editor.getLabelControl(getFieldEditorParent()).getBackground();
Text text = editor.getTextControl(getFieldEditorParent());
text.setBackground(background);
text.setEditable(false);
}
@Override
protected Control createContents(Composite parent) {
return super.createContents(parent);
}
/**
* @param info
*/
private void createFieldEditorsForParameters(final IProblemPreference info) {
if (info == null)
return;
if (info.getKey() == FileScopeProblemPreference.KEY)
return; // skip the scope
if (info.getKey() == LaunchModeProblemPreference.KEY)
return; // skip the launch
switch (info.getType()) {
case TYPE_STRING: {
StringFieldEditor fe = new StringFieldEditor(info.getQualifiedKey(), info.getLabel(), getFieldEditorParent());
addField(fe);
break;
}
case TYPE_BOOLEAN: {
BooleanFieldEditor fe = new BooleanFieldEditor(info.getQualifiedKey(), info.getLabel(), getFieldEditorParent());
addField(fe);
break;
}
case TYPE_LIST:
ListEditor le = new ListEditor(info.getQualifiedKey(), info.getLabel(), getFieldEditorParent()) {
@Override
protected String[] parseString(String stringList) {
ListProblemPreference list = (ListProblemPreference) info;
IProblemPreference[] childDescriptors = list.getChildDescriptors();
if (childDescriptors.length == 0)
return new String[0];
String res[] = new String[childDescriptors.length];
for (int i = 0; i < childDescriptors.length; i++) {
IProblemPreference item = childDescriptors[i];
res[i] = String.valueOf(item.getValue());
}
return res;
}
@Override
protected String getNewInputObject() {
ListProblemPreference list = (ListProblemPreference) info;
String label = list.getChildDescriptor().getLabel();
InputDialog dialog = new InputDialog(getShell(), CodanUIMessages.ParametersComposite_NewValue, label,
"", null); //$NON-NLS-1$
if (dialog.open() == Window.OK) {
return dialog.getValue();
}
return null;
}
@Override
protected String createList(String[] items) {
ListProblemPreference list = (ListProblemPreference) info.clone();
list.clear();
for (int i = 0; i < items.length; i++) {
String val = items[i];
list.addChildValue(val);
}
return list.exportValue();
}
};
addField(le);
break;
case TYPE_MAP:
IProblemPreference[] childrenDescriptor = ((IProblemPreferenceCompositeDescriptor) info).getChildDescriptors();
for (int i = 0; i < childrenDescriptor.length; i++) {
IProblemPreference desc = childrenDescriptor[i];
createFieldEditorsForParameters(desc);
}
break;
case TYPE_CUSTOM: {
StringFieldEditor fe = new StringFieldEditor(info.getQualifiedKey(), info.getLabel(), getFieldEditorParent());
addField(fe);
break;
}
case TYPE_FILE: {
FileFieldEditor fe = new FileFieldEditor(info.getQualifiedKey(), info.getLabel(), getFieldEditorParent());
addField(fe);
break;
}
default:
throw new UnsupportedOperationException(info.getType().toString());
}
}
};
load(problem);
page.setPreferenceStore(prefStore);
page.createControl(parent);
page.getControl().setLayoutData(new GridData(GridData.FILL_BOTH));
}
/**
* @param problem
*/
public void load(final IProblem problem) {
IProblemPreference info = problem.getPreference();
if (info == null) {
Label label = new Label(this, 0);
label.setText(CodanUIMessages.ParametersComposite_None);
} else {
initPrefStore(info);
}
prefStore.setDefault(PREF_ENABLED, problem.isEnabled());
if (problem.getMessagePattern() == NO_CHANGE) {
prefStore.setDefault(PREF_SEVERITY, NO_CHANGE);
} else {
prefStore.setDefault(PREF_SEVERITY, problem.getSeverity().toString());
}
prefStore.setDefault(PREF_MESSAGE, problem.getMessagePattern());
}
public void save(IProblemWorkingCopy problem) {
page.performOk();
savePrefStore(problem.getPreference());
problem.setEnabled(prefStore.getBoolean(PREF_ENABLED));
String severity = prefStore.getString(PREF_SEVERITY);
if (!severity.equals(NO_CHANGE))
problem.setSeverity(CodanSeverity.valueOf(severity));
String message = prefStore.getString(PREF_MESSAGE);
if (!message.equals(NO_CHANGE))
problem.setMessagePattern(message);
}
private void savePrefStore(IProblemPreference desc) {
if (desc == null)
return;
String key = desc.getQualifiedKey();
switch (desc.getType()) {
case TYPE_STRING:
desc.setValue(prefStore.getString(key));
break;
case TYPE_BOOLEAN:
desc.setValue(prefStore.getBoolean(key));
break;
case TYPE_INTEGER:
desc.setValue(prefStore.getInt(key));
break;
case TYPE_FILE:
desc.setValue(new File(prefStore.getString(key)));
break;
case TYPE_LIST:
desc.importValue(prefStore.getString(key));
break;
case TYPE_CUSTOM:
desc.importValue(prefStore.getString(key));
break;
case TYPE_MAP:
IProblemPreference[] childrenDescriptor = ((IProblemPreferenceCompositeDescriptor) desc).getChildDescriptors();
for (int i = 0; i < childrenDescriptor.length; i++) {
IProblemPreference chi = childrenDescriptor[i];
savePrefStore(chi);
}
break;
default:
throw new UnsupportedOperationException(desc.getType().toString());
}
}
private void initPrefStore(IProblemPreference desc) {
if (desc == null || desc.getValue() == null)
return;
String key = desc.getQualifiedKey();
switch (desc.getType()) {
case TYPE_STRING:
prefStore.setDefault(key, (String) desc.getValue());
//prefStore.setValue(key, (String) desc.getValue());
break;
case TYPE_BOOLEAN:
prefStore.setDefault(key, (Boolean) desc.getValue());
//prefStore.setValue(key, (Boolean) desc.getValue());
break;
case TYPE_INTEGER:
prefStore.setDefault(key, (Integer) desc.getValue());
//prefStore.setValue(key, (Integer) desc.getValue());
break;
case TYPE_FILE:
prefStore.setDefault(key, ((File) desc.getValue()).getPath());
//prefStore.setValue(key, ((File) desc.getValue()).getPath());
break;
case TYPE_LIST:
prefStore.setDefault(key, desc.exportValue());
//prefStore.setValue(key, desc.exportValue());
break;
case TYPE_CUSTOM:
prefStore.setDefault(key, desc.exportValue());
//prefStore.setValue(key, desc.exportValue());
break;
case TYPE_MAP:
IProblemPreference[] childrenDescriptor = ((IProblemPreferenceCompositeDescriptor) desc).getChildDescriptors();
for (int i = 0; i < childrenDescriptor.length; i++) {
IProblemPreference chi = childrenDescriptor[i];
initPrefStore(chi);
}
break;
default:
throw new UnsupportedOperationException(desc.getType().toString());
}
}
/**
* @return the problem
*/
public IProblem getProblem() {
return problem;
}
}