/*
* Copyright (C) 2014-2015 Daniel Dietsch (dietsch@informatik.uni-freiburg.de)
* Copyright (C) 2015 University of Freiburg
*
* This file is part of the ULTIMATE GUIGeneratedPreferencePages plug-in.
*
* The ULTIMATE GUIGeneratedPreferencePages plug-in is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ULTIMATE GUIGeneratedPreferencePages plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the ULTIMATE GUIGeneratedPreferencePages plug-in. If not, see .
*
* Additional permission under GNU GPL version 3 section 7:
* If you modify the ULTIMATE GUIGeneratedPreferencePages plug-in, or any covered work, by linking
* or combining it with Eclipse RCP (or a modified version of Eclipse RCP),
* containing parts covered by the terms of the Eclipse Public License, the
* licensors of the ULTIMATE GUIGeneratedPreferencePages plug-in grant you additional permission
* to convey the resulting work.
*/
package de.uni_freiburg.informatik.ultimate.gui.preferencepages;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.ColorFieldEditor;
import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.DoubleFieldEditor;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.IntegerFieldEditor;
import org.eclipse.jface.preference.PathEditor;
import org.eclipse.jface.preference.RadioGroupFieldEditor;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import de.uni_freiburg.informatik.ultimate.core.model.preferences.BaseUltimatePreferenceItem;
import de.uni_freiburg.informatik.ultimate.core.model.preferences.UltimatePreferenceItem;
import de.uni_freiburg.informatik.ultimate.core.model.preferences.UltimatePreferenceItem.IUltimatePreferenceItemValidator;
import de.uni_freiburg.informatik.ultimate.core.model.preferences.UltimatePreferenceItemGroup;
import de.uni_freiburg.informatik.ultimate.core.preferences.RcpPreferenceProvider;
import de.uni_freiburg.informatik.ultimate.gui.customeditors.KeyValueGridEditor;
import de.uni_freiburg.informatik.ultimate.gui.customeditors.MultiLineTextFieldEditor;
import de.uni_freiburg.informatik.ultimate.gui.customeditors.UltimateLabelFieldEditor;
/**
*
* @author Daniel Dietsch (dietsch@informatik.uni-freiburg.de)
*
*/
public class UltimateGeneratedPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
private final String mPluginID;
private final BaseUltimatePreferenceItem[] mDefaultPreferences;
private final String mTitle;
private final ScopedPreferenceStore mPreferenceStore;
private final Map> mCheckedFields;
private final ArrayDeque mActiveGroups = new ArrayDeque<>();
private final List mGroups = new ArrayList<>();
private int mMinColumns = 0;
public UltimateGeneratedPreferencePage(final String pluginID, final String title,
final BaseUltimatePreferenceItem[] preferences) {
super(GRID);
mPluginID = pluginID;
mDefaultPreferences = preferences;
mTitle = title;
mPreferenceStore = new ScopedPreferenceStore(new RcpPreferenceProvider(mPluginID).getScopeContext(), mPluginID);
mCheckedFields = new HashMap<>();
setPreferenceStore(mPreferenceStore);
setTitle(mTitle);
}
public UltimateGeneratedPreferencePage copy() {
return new UltimateGeneratedPreferencePage(mPluginID, mTitle, mDefaultPreferences);
}
@Override
protected void createFieldEditors() {
createFieldEditors(Arrays.asList(mDefaultPreferences));
adjustGroupGrids();
}
protected void createFieldEditors(final List items) {
for (final BaseUltimatePreferenceItem prefItem : items) {
if (prefItem instanceof UltimatePreferenceItem) {
final UltimatePreferenceItem> item = (UltimatePreferenceItem>) prefItem;
final FieldEditor editor;
switch (item.getType()) {
case Label:
editor = createLabel(item.getLabel(), item.isExperimental());
break;
case Integer:
editor = createIntegerFieldEditor(item.getLabel(), item.isExperimental());
break;
case Double:
editor = createDoubleFieldEditor(item.getLabel(), item.isExperimental());
break;
case Boolean:
editor = createBooleanFieldEditor(item.getLabel(), item.isExperimental());
break;
case Directory:
editor = createDirectoryEditor(item.getLabel(), item.isExperimental());
break;
case String:
editor = createStringEditor(item.getLabel(), item.isExperimental());
break;
case Combo:
editor = createComboEditor(item, item.isExperimental());
break;
case Radio:
editor = createRadioGroupFieldEditor(item, item.isExperimental());
break;
case Path:
editor = createPathFieldEditor(item, item.isExperimental());
break;
case File:
editor = createFileFieldEditor(item, item.isExperimental());
break;
case MultilineString:
editor = createMultilineFieldEditor(item.getLabel(), item.isExperimental());
break;
case Color:
editor = createColorEditor(item.getLabel(), item.isExperimental());
break;
case KeyValue:
editor = createKeyValueEditor(item.getLabel(), item.isExperimental());
break;
default:
throw new UnsupportedOperationException(
"You need to implement the new enum type \"" + item.getType() + "\" here");
}
mMinColumns = Integer.max(mMinColumns, editor.getNumberOfControls());
final String tooltip = item.getDescription();
if (tooltip != null) {
setTooltip(editor, getFieldEditorParent(), tooltip);
}
addField(editor);
if (item.getPreferenceValidator() != null) {
mCheckedFields.put(editor, item);
}
} else if (prefItem instanceof UltimatePreferenceItemGroup) {
final var group = (UltimatePreferenceItemGroup) prefItem;
beginGroupBox(group.getLabel(), group.getDescription(), 2);
createFieldEditors(group.getItems());
endGroupBox();
}
}
}
protected void adjustGroupGrids() {
for (final var group : mGroups) {
group.adjustForNumColumns(mMinColumns);
}
}
private static void setTooltip(final FieldEditor editor, final Composite parent, final String tooltip) {
if (editor instanceof BooleanFieldEditor) {
((BooleanFieldEditor) editor).getDescriptionControl(parent).setToolTipText(tooltip);
} else {
final Label label = editor.getLabelControl(parent);
label.setToolTipText(tooltip);
}
}
@Override
protected void checkState() {
super.checkState();
if (isValid()) {
for (final FieldEditor entry : mCheckedFields.keySet()) {
checkState(entry);
}
}
}
@Override
public void propertyChange(final PropertyChangeEvent event) {
super.propertyChange(event);
if (event.getProperty().equals(FieldEditor.VALUE)) {
checkState((FieldEditor) event.getSource());
}
}
@Override
public void init(final IWorkbench workbench) {
// not needed
}
@Override
public boolean performOk() {
try {
mPreferenceStore.save();
} catch (final IOException e) {
e.printStackTrace();
}
return super.performOk();
}
private void beginGroupBox(final String label, final String description, final int numColumns) {
mActiveGroups.push(new ItemGroupBox(label, description, getFieldEditorParent(), numColumns));
}
private void endGroupBox() {
final var finished = mActiveGroups.pop();
mGroups.add(finished);
}
@Override
protected Composite getFieldEditorParent() {
if (mActiveGroups.isEmpty()) {
return super.getFieldEditorParent();
}
final var topGroup = mActiveGroups.peek();
return topGroup.getFieldEditorParent();
}
@SuppressWarnings("unchecked")
private void checkState(final FieldEditor editor) {
if (editor.isValid()) {
final UltimatePreferenceItem> preferenceDescriptor = mCheckedFields.get(editor);
if (preferenceDescriptor == null) {
return;
}
final IUltimatePreferenceItemValidator> validator = preferenceDescriptor.getPreferenceValidator();
switch (preferenceDescriptor.getType()) {
case Boolean:
validateField((IUltimatePreferenceItemValidator) validator,
((BooleanFieldEditor) editor).getBooleanValue());
break;
case Integer:
validateField((IUltimatePreferenceItemValidator) validator,
((IntegerFieldEditor) editor).getIntValue());
break;
case Double:
validateField((IUltimatePreferenceItemValidator) validator,
((DoubleFieldEditor) editor).getDoubleValue());
break;
case Directory:
case Path:
case String:
case File:
case Color:
validateField((IUltimatePreferenceItemValidator) validator,
((StringFieldEditor) editor).getStringValue());
break;
case MultilineString:
validateField((IUltimatePreferenceItemValidator) validator,
((MultiLineTextFieldEditor) editor).getStringValue());
break;
case KeyValue:
validateField((IUltimatePreferenceItemValidator